diff --git a/Gemfile b/Gemfile index 958824e827..11008d9431 100644 --- a/Gemfile +++ b/Gemfile @@ -34,9 +34,6 @@ gem 'jsonify-rails' # Use R2 for RTL conversion gem 'r2' -# Use ejs for javascript templates -gem 'ejs' - # Load rails plugins gem 'rails-i18n', "~> 4.0.0" gem 'dynamic_form' diff --git a/Gemfile.lock b/Gemfile.lock index 08bb2f1c32..d8dae468a3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -48,7 +48,6 @@ GEM dalli (2.6.4) deadlock_retry (1.2.0) dynamic_form (1.1.4) - ejs (1.1.1) erubis (2.7.0) execjs (2.0.2) faraday (0.8.8) @@ -181,7 +180,6 @@ DEPENDENCIES dalli deadlock_retry (>= 1.2.0) dynamic_form - ejs htmlentities http_accept_language (~> 2.0.0) httpclient diff --git a/Vendorfile b/Vendorfile index 4fc1e53485..2d728ab1eb 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 0000000000..d5479eea39 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 0000000000..bc76ee0975 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 0000000000..65d09d73d6 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 0000000000..da3f92c5d9 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 5b33f7e54f..b1451fd7d4 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 108c38c87a..e7490c84cb 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 3641c68abc..b61018d135 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 2b8bc5d26c..25d68d0ea0 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,27 @@ 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)); - - if (bounds && $(link).hasClass("bbox")) args.bbox = normalBounds(bounds).toBBoxString(); - if (object && $(link).hasClass("object")) args[object.type] = object.id; + editlink = $(link).hasClass("editlink"); - 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 (object && editlink) { + href += '?' + object.type + '=' + object.id; + } - if (layers && $(link).hasClass("layers")) { - args.layers = layers; - } + var 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 +90,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,12 +111,21 @@ function escapeHTML(string) { }); } -/* - * Forms which have been cached by rails may have the wrong - * authenticity token, so patch up any forms with the correct - * token taken from the page header. - */ +function maximiseMap() { + $("#content").addClass("maximised"); +} + +function minimiseMap() { + $("#content").removeClass("maximised"); +} + $(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 565af41afc..0000000000 --- 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 d9c09bab49..0000000000 --- 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 1aa728ea0f..5a19cb4d63 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 7de65190eb..0000000000 --- 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 0809bef78b..0000000000 --- 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 d84b8ae247..3ce1a02da3 100644 --- a/app/assets/javascripts/index.js +++ b/app/assets/javascripts/index.js @@ -9,75 +9,74 @@ //= 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); + $('#flash').empty(); + $('#sidebar_loader').hide(); + + var content = $(xhr.responseText); + + if (xhr.getResponseHeader('X-Page-Title')) { + document.title = xhr.getResponseHeader('X-Page-Title'); + } + + $('head') + .find('link[type="application/atom+xml"]') + .remove(); + + $('head') + .append(content.filter('link[type="application/atom+xml"]')); + + $('#sidebar_content').html(content.not('link[type="application/atom+xml"]')); + + 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 +84,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 +102,7 @@ $(document).ready(function () { L.OSM.layers({ position: position, - layers: layers, + layers: map.baseLayers, sidebar: sidebar }).addTo(map); @@ -136,9 +125,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 +163,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 +208,91 @@ $(document).ready(function () { }); } - initializeSearch(map); - initializeExport(map); - initializeBrowse(map, params); - initializeNotes(map, params); -}); + OSM.Index = function(map) { + var page = {}; + + page.pushstate = function() { + $("#content").addClass("overlay-sidebar"); + map.invalidateSize({pan: false}) + .panBy([-350, 0], {animate: false}); + }; + + page.load = function() { + return map.getState(); + }; + + page.popstate = function() { + $("#content").addClass("overlay-sidebar"); + map.invalidateSize({pan: false}); + }; + + 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); + + OSM.router = OSM.Router(map, { + "/": OSM.Index(map), + "/search": OSM.Search(map), + "/export": OSM.Export(map), + "/note/new": OSM.NewNote(map), + "/history/friends": history, + "/history/nearby": history, + "/history": history, + "/user/:display_name/history": history, + "/note/:id": OSM.Note(map), + "/:type/:id(/history)": OSM.Browse(map) + }); -function updateLocation() { - updatelinks(this.getCenter().wrap(), - this.getZoom(), - this.getLayersCode(), - this.getBounds().wrap()); + OSM.router.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.router.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.router.route("/search?query=" + encodeURIComponent(query) + OSM.formatHash(map)); + } else { + OSM.router.route("/" + OSM.formatHash(map)); + } + }); + + $(".describe_location").on("click", function(e) { + e.preventDefault(); + var precision = zoomPrecision(map.getZoom()); + OSM.router.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 d8de69974f..21f0ae71a3 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,128 +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; + var bounds = map.getBounds(); + if (!browseBounds || !browseBounds.contains(bounds)) { + getData(); } - - getData(); } 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(); + 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')); - var url = "/api/" + OSM.API_VERSION + "/map?bbox=" + bounds.toBBoxString(); /* @@ -181,35 +92,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) { @@ -219,29 +109,11 @@ function initializeBrowse(map, params) { } dataLoader = null; + browseBounds = bounds; } }); } - 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.router.route('/' + 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 aec35ed2b1..053f5169fa 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 0000000000..639705f91c --- /dev/null +++ b/app/assets/javascripts/index/history.js @@ -0,0 +1,137 @@ +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.router.route($("#changeset_" + id).find(".changeset_id").attr("href")); + } + + function loadData() { + var data = {}; + + if (window.location.pathname === '/history') { + data = {bbox: map.getBounds().wrap().toBBoxString()}; + } + + $.ajax({ + url: window.location.pathname, + method: "GET", + data: data, + 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); + } + + if (window.location.pathname !== '/history') { + var bounds = group.getBounds(); + if (bounds.isValid()) map.fitBounds(bounds); + } + } + + page.pushstate = page.popstate = function(path) { + $("#history_tab").addClass("current"); + OSM.loadSidebarContent(path, page.load); + }; + + page.load = function() { + map.addLayer(group); + + if (window.location.pathname === '/history') { + map.on("moveend", loadData) + } + + loadData(); + }; + + page.unload = function() { + map.removeLayer(group); + + if (window.location.pathname === '/history') { + map.off("moveend", loadData) + } + + $("#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 0000000000..6f734a35b1 --- /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.router.route('/note/new'); + }); + + 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('/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 0000000000..aa746265cb --- /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 = {}, + halo, currentNote; + + 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(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 () { + 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(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(), + latLng = data.coordinates.split(','); + + if (!window.location.hash) { + OSM.router.moveListenerOff(); + map.once('moveend', OSM.router.moveListenerOn); + map.getZoom() > 15 ? map.panTo(latLng) : map.setView(latLng, 16); + } + + if (!map.hasLayer(halo)) { + halo = L.circleMarker(latLng, { + weight: 2.5, + radius: 20, + fillOpacity: 0.5, + color: "#FF6200" + }); + map.addLayer(halo); + } + + if (map.hasLayer(currentNote)) map.removeLayer(currentNote); + currentNote = L.marker(latLng, { + icon: noteIcons[data.status], + opacity: 1, + clickable: true + }); + map.addLayer(currentNote); + }; + + page.unload = function () { + if (map.hasLayer(halo)) map.removeLayer(halo); + if (map.hasLayer(currentNote)) map.removeLayer(currentNote); + }; + + return page; +}; diff --git a/app/assets/javascripts/index/notes.js.erb b/app/assets/javascripts/index/notes.js.erb index 8972d6bf9d..841ae1f7bd 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.router.route('/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.8, + 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 dc4df821e8..c1c95a3e43 100644 --- a/app/assets/javascripts/index/search.js +++ b/app/assets/javascripts/index/search.js @@ -1,77 +1,79 @@ -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(); - } - - $("#sidebar_content").on("click", ".search_results_entry a.set_position", clickSearchResult); +OSM.Search = function(map) { + $(".search_form input[name=query]") + .on("focus", function() { + $(".describe_location").fadeOut(100); + }) + .on("blur", function() { + $(".describe_location").fadeIn(100); + }); - var marker = L.marker([0, 0], {icon: getUserIcon()}); + $("#sidebar_content") + .on("click", ".search_more a", clickSearchMore) + .on("click", ".search_results_entry a.set_position", clickSearchResult); - 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.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 cc86736ef8..58bfbf6d2a 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 2534a91c29..7703529b87 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.router.moveListenerOff(); + map.once('moveend', OSM.router.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 01fc0c80a4..d4c8295320 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 98299070d2..0000000000 --- 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 5c555a25ac..392bf5e0c6 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,13 @@ 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; + // Old-style object parameters; still in use for edit links e.g. /edit?way=1234 + 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 +62,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 +93,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 +102,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 +148,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 0000000000..8661f95dcc --- /dev/null +++ b/app/assets/javascripts/router.js @@ -0,0 +1,180 @@ +/* + OSM.Router implements pushState-based navigation for the main page and + other pages that use a sidebar+map based layout (export, search results, + history, and browse pages). + + For browsers without pushState, it falls back to full page loads, which all + of the above pages support. + + The router is initialized with a set of routes: a mapping of URL path templates + to route controller objects. Path templates can contain placeholders + (`/note/:id`) and optional segments (`/:type/:id(/history)`). + + Route controller objects can define four methods that are called at defined + times during routing: + + * The `load` method is called by the router when a path which matches the + route's path template is loaded via a normal full page load. It is passed + as arguments the URL path plus any matching arguments for placeholders + in the path template. + + * The `pushstate` method is called when a page which matches the route's path + template is loaded via pushState. It is passed the same arguments as `load`. + + * The `popstate` method is called when returning to a previously + pushState-loaded page via popstate (i.e. browser back/forward buttons). + + * The `unload` method is called on the exiting route controller when navigating + via pushState or popstate to another route. + + Note that while `load` is not called by the router for pushState-based loads, + it's frequently useful for route controllers to call it manually inside their + definition of the `pushstate` and `popstate` methods. + + An instance of OSM.Router is assigned to `OSM.router`. To navigate to a new page + via pushState (with automatic full-page load fallback), call `OSM.router.route`: + + OSM.router.route('/way/1234'); + + If `route` is passed a path that matches one of the path templates, it performs + the appropriate actions and returns true. Otherwise it returns false. + + OSM.Router also handles updating the hash portion of the URL containing transient + map state such as the position and zoom level. Some route controllers may wish to + temporarily suppress updating the hash (for example, to omit the hash on pages + such as `/way/1234` unless the map is moved). This can be done by calling + `OSM.router.moveListenerOff` and `OSM.router.moveListenerOn`. + */ +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 = {}; + + 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.route = 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.route = 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 912197b9f2..0000000000 --- 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 d80c689228..0000000000 --- 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 c579070e1d..0000000000 --- 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 7b8a193ad2..0000000000 --- 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 003971088c..0000000000 --- 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 bea60ed4a5..0000000000 --- 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 d31f5bb826..6a0d38dd5d 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 56c454ac4a..aa28e99e9d 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,21 @@ $(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); + if (navigator.geolocation) { + // handle firefox's weird implementation + // https://bugzilla.mozilla.org/show_bug.cgi?id=675533 + window.setTimeout(manualEdit, 4000); - navigator.geolocation.getCurrentPosition(geoSuccess, manualEdit); + navigator.geolocation.getCurrentPosition(geoSuccess, manualEdit); + } else { + 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 179f0c1022..ff9dad9b4a 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 42467adb3a..56285564fd 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,10 @@ abbr, acronym { cursor: help; } +strong { + font-weight: bold; +} + /* Micro Clearfix | Details: http://nicolasgallagher.com/micro-clearfix-hack/ */ .clearfix:before, @@ -88,12 +83,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 +101,7 @@ body { margin: 0px; padding: 0px; text-align: left; + height: 100%; } body.slim { @@ -112,36 +109,20 @@ body.slim { } h1, h2, h3 { - margin-top: $lineheight/2; - margin-bottom: $lineheight; - font-weight: bold; + font-weight: 600; 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: 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 +134,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 +146,8 @@ h6:first-child { margin-right: $lineheight/4; } +.red { color: $red; } + /* Rules for icons */ .icon { @@ -182,10 +158,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 +172,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 +180,10 @@ h6:first-child { /* Rules for links */ a { - color: #00f; + color: #24d; text-decoration: none; + -webkit-appearance: none; + outline: 0; &:hover { text-decoration: underline; } @@ -234,7 +209,7 @@ table { line-height: $lineheight; } th { - font-weight: bold; + font-weight: 600; vertical-align: top; } td { @@ -242,364 +217,215 @@ 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: 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: 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 +435,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 +565,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 +594,188 @@ 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: 12px; + + h2 { + padding: $lineheight $lineheight $lineheight/2; + } + + h3, h4 { + margin-top: $lineheight; + margin-bottom: $lineheight/2; + font-size: 13px; + } - .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; + .welcome { + display: none; } -} -.layers-ui, -.share-ui { - ul, li:last-child, p:last-child { - margin-bottom: 0; + .overlay-sidebar #sidebar { + position: absolute; + z-index: 1000; + height: auto; + border-bottom-right-radius: 5px; + overflow: hidden; + .welcome { + display: block; + } + #sidebar_content { + display: none; + } } -} -.layers-ui { - li { - border-radius: 4px; + .welcome { + p { + padding: $lineheight/2 $lineheight $lineheight; + font-size: 110%; + 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; + } + } + } + + #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: 600; + 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 +834,7 @@ a.donate { } } -.leaflet-top.leaflet-right { +.leaflet-top { top: $lineheight/2 !important; .leaflet-control { margin-right: 0px !important; @@ -894,34 +853,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 +868,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 +962,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 +979,245 @@ 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; + } + } + + .browse-section:last-of-type { + 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: 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 { + overflow: hidden; + 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%; + overflow: hidden; } } -.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 +1225,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 +1257,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 +1401,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 +1459,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 +1554,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 +1563,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 +1695,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 */ @@ -1918,12 +1861,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 +1871,7 @@ abbr.geo { .rsssmall { position: relative; - top: 5px; + top: 3px; } /* General styles for action lists / subnavs / pager navs */ @@ -1952,8 +1889,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 +1899,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 +1968,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 +2001,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 +2183,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 +2224,7 @@ a.button { .dropdown-menu { position: absolute; top: 100%; - left: 0; + left: -1px; z-index: 1000; display: none; float: left; @@ -2396,6 +2234,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 +2276,7 @@ a.button { .dropdown-submenu:focus > a { color: #ffffff; text-decoration: none; - background-color: #0081c2; + background-color: $green; } .dropdown-menu > .active > a, @@ -2445,7 +2284,7 @@ a.button { .dropdown-menu > .active > a:focus { color: #ffffff; text-decoration: none; - background-color: #0081c2; + background-color: $green; outline: 0; } @@ -2559,3 +2398,152 @@ 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: 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 0000000000..b26b29105b --- /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 84efa0e2e1..fa04314b1f 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 419abeac4e..e9d0a47790 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 !important; } -#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 fec202ca54..7754f72fde 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -418,6 +418,10 @@ def fetch_body request.body.rewind end + def map_layout + request.xhr? ? 'xhr' : '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 119792167d..e16ec29147 100644 --- a/app/controllers/browse_controller.rb +++ b/app/controllers/browse_controller.rb @@ -1,74 +1,66 @@ 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] + before_filter :require_oauth + 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 @@ -80,9 +72,6 @@ def changeset 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 36b3b5124e..5cd59c780e 100644 --- a/app/controllers/changeset_controller.rb +++ b/app/controllers/changeset_controller.rb @@ -250,91 +250,51 @@ def update ## # list edits (open changesets) in reverse chronological order def list - if request.format == :atom and params[:page] - redirect_to params.merge({ :page => nil }), :status => :moved_permanently + if request.format == :atom and params[:max_id] + redirect_to params.merge({ :max_id => nil }), :status => :moved_permanently + return + end + + if params[:display_name] + user = User.find_by_display_name(params[:display_name]) + if !user || !user.active? + render_unknown_user params[:display_name] + return + end + end + + if (params[:friends] || params[:nearby]) && !@user && request.format == :html + require_user + return + end + + if request.format == :html and !params[:bbox] + require_oauth + render :action => :history, :layout => map_layout else changesets = conditions_nonempty(Changeset.all) if params[:display_name] - user = User.find_by_display_name(params[:display_name]) - - if user and user.active? - if user.data_public? or user == @user - changesets = changesets.where(:user_id => user.id) - else - changesets = changesets.where("false") - end + if user.data_public? or user == @user + changesets = changesets.where(:user_id => user.id) else - render_unknown_user params[:display_name] - return - end - end - - if params[:friends] - if @user - changesets = changesets.where(:user_id => @user.friend_users.public) - elsif request.format == :html - require_user - return - end - end - - if params[:nearby] - if @user - changesets = changesets.where(:user_id => @user.nearby) - elsif request.format == :html - require_user - return + changesets = changesets.where("false") end + elsif params[:bbox] + changesets = conditions_bbox(changesets, BoundingBox.from_bbox_params(params)) + elsif params[:friends] && @user + changesets = changesets.where(:user_id => @user.friend_users.public) + elsif params[:nearby] && @user + changesets = changesets.where(:user_id => @user.nearby) 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) - 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.id 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 b37810ca90..00eba741f5 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 6db70a6f37..692ae24ddb 100644 --- a/app/controllers/geocoder_controller.rb +++ b/app/controllers/geocoder_controller.rb @@ -7,6 +7,7 @@ class GeocoderController < ApplicationController before_filter :authorize_web before_filter :set_locale + before_filter :require_oauth, :only => [:search] def search normalize_params @@ -29,6 +30,8 @@ def search @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 cea37fbf36..1757e771a9 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 @@ def permalink def key expires_in 7.days, :public => true + render :layout => false end def edit @@ -44,8 +46,6 @@ def edit 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 @@ def copyright 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 @@ def id 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 4765cb35b3..5d61e8c630 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -94,6 +94,14 @@ def friendly_date(date) 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 c4e4d425a5..cf13c27958 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 @@ def format_value(key, value) 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 0000000000..cae1335c4c --- /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 c74cba28e3..ce6c7eafa7 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 @@ def result_to_html(result) 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 f2bff861f7..e0eef269b4 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 @@ def note_author(author, link_options = {}) 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 0000000000..da4ad8967e --- /dev/null +++ b/app/helpers/title_helper.rb @@ -0,0 +1,6 @@ +module TitleHelper + def set_title(title = false) + response.headers["X-Page-Title"] = t('layouts.project_name.title') + (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 7a0deac50d..0000000000 --- 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 7c8165c67f..ede9e14c5b 100644 --- a/app/views/browse/_common_details.html.erb +++ b/app/views/browse/_common_details.html.erb @@ -1,39 +1,33 @@ -
    -
    - <% 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.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) + %> +
    -
    -

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

    -

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

    -
    +
    + <%= t 'browse.version' %> + #<%= h(common_details.version) %> + · + <%= t 'browse.in_changeset' %> + #<%= link_to common_details.changeset_id, :action => :changeset, :id => common_details.changeset_id %> +
    - <% if common_details.changeset.tags['comment'].present? %> -
    -

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

    -

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

    -
    - <% end %> +<% if @type == "node" %> +
    + Location: + <%= link_to(content_tag(:span, number_with_delimiter(common_details.lat), :class => "latitude") + ", " + content_tag(:span, number_with_delimiter(common_details.lon), :class => "longitude"), {:controller => 'site', :action => 'index', :lat => h(common_details.lat), :lon => h(common_details.lon), :zoom => "18"}) %>
    -<%= render :partial => "tag_details", :object => common_details %> +<% end %> + +<%= 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 ed703665d1..0000000000 --- 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 0856044c80..0000000000 --- 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 0000000000..2c2cdd4c0e --- /dev/null +++ b/app/views/browse/_node.html.erb @@ -0,0 +1,23 @@ +<% 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 8dec338d69..0000000000 --- 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 f236b44650..67f1c75a3b 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 0000000000..6befb8aae2 --- /dev/null +++ b/app/views/browse/_relation.html.erb @@ -0,0 +1,23 @@ +<% 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 1c0f4c93c0..0000000000 --- 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 2983318320..b9296fa487 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 9d0a2af546..090a23e7c3 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 0000000000..fd419586fb --- /dev/null +++ b/app/views/browse/_way.html.erb @@ -0,0 +1,35 @@ +<% 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 6bff887b3c..0000000000 --- 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 96a5280a53..736abf12fb 100644 --- a/app/views/browse/changeset.html.erb +++ b/app/views/browse/changeset.html.erb @@ -1,18 +1,72 @@ -<% 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) %> +

    + +
    +

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

    +
    <%= changeset_details(@changeset) %>
    + + <%= render :partial => "tag_details", :object => @changeset.tags.except('comment') %> -<%= render :partial => "navigation" %> + <% 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 %> -<% if @changeset.has_valid_bbox? %> -<%= render :partial => "map", :object => @changeset %> + <% 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 %> +
    + +<% if @next_by_user || @prev_by_user %> +
    + <% if @prev_by_user %> + <%= link_to "<< #{@prev_by_user.id}", :id => @prev_by_user.id %> + · + <% end %> + <%= + user = (@prev_by_user || @next_by_user).user.display_name + link_to user, :controller => "changeset", :action => "list", :display_name => user + %> + <% if @next_by_user %> + · + <%= link_to "#{@next_by_user.id} >>", :id => @next_by_user.id %> + <% end %> +
    <% end %> -<%= render :partial => "changeset_details", :object => @changeset %> \ No newline at end of file + +
    + <%= 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 0000000000..1e0f118d83 --- /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 0000000000..fa483bfb06 --- /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 0000000000..49922494e2 --- /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 f41562a7fe..0000000000 --- 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 e37f0e037f..0000000000 --- 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 f536ef9ffe..a8974b4747 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 31fd00f014..5ab29e0d1d 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', :id => @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 3ba3550548..0000000000 --- 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 e0640d9007..0000000000 --- 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 12012a0299..0000000000 --- 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 15a0dcad82..0000000000 --- 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 49058edc10..0000000000 --- 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/_bbox.atom.builder b/app/views/changeset/_bbox.atom.builder deleted file mode 100644 index de3b1f1129..0000000000 --- a/app/views/changeset/_bbox.atom.builder +++ /dev/null @@ -1 +0,0 @@ -xml.a(bbox.to_s, :href => url_for(:controller => "site", :action => "index", :minlon => bbox.min_lon, :minlat => bbox.min_lat, :maxlon => bbox.max_lon, :maxlat => bbox.max_lat, :box => "yes")) diff --git a/app/views/changeset/_bbox.html.erb b/app/views/changeset/_bbox.html.erb deleted file mode 100644 index f9424befd8..0000000000 --- a/app/views/changeset/_bbox.html.erb +++ /dev/null @@ -1 +0,0 @@ -<%= link_to bbox.to_s, :controller => "site", :action => "index", :minlon => bbox.min_lon, :minlat => bbox.min_lat, :maxlon => bbox.max_lon, :maxlat => bbox.max_lat, :box => "yes" %> diff --git a/app/views/changeset/_changeset.html.erb b/app/views/changeset/_changeset.html.erb index 3e4871ec06..5c5ad670b6 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 46b4635c88..0000000000 --- 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 fe8da2b383..0000000000 --- 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 9730059eed..0000000000 --- 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 0e95076504..0000000000 --- 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 0000000000..77118b4b4b --- /dev/null +++ b/app/views/changeset/history.html.erb @@ -0,0 +1,30 @@ +<% content_for :auto_discovery_link_tag do -%> + <% unless params[:friends] or params[:nearby] -%> + <%= auto_discovery_link_tag :atom, params.merge(:max_id => nil, :xhr => 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 591f269b61..619dc4a082 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 ee8610574b..68bdf1e23f 100644 --- a/app/views/changeset/list.html.erb +++ b/app/views/changeset/list.html.erb @@ -1,37 +1,15 @@ -<% 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[:bbox] %> +
    <%= t(params[:max_id] ? 'changeset.list.no_more_area' : 'changeset.list.empty_area') %>
    +<% elsif params[:display_name] %> +
    <%= t(params[:max_id] ? 'changeset.list.no_more_user' : 'changeset.list.empty_user') %>
    <% else %> -

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

    +
    <%= t(params[:max_id] ? 'changeset.list.no_more' : '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 fd90b75014..9dc800cff5 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 2939ec7e62..0767bd402f 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 0bc1ac5bb7..0000000000 --- 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 3c471076cf..d990b7f0ec 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 6e25588b62..ac655147a9 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 0000000000..a4d93cc0ec --- /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 b7d9d7fdfe..0000000000 --- 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 a3cbbc2072..51ef3fe415 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 0a4fb143fb..13f7070816 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 761975466b..ae313e1f26 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 0000000000..1765072070 --- /dev/null +++ b/app/views/site/export.html.erb @@ -0,0 +1,48 @@ +<% 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.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 0000000000..a1b1adb922 --- /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 fde4a07cd3..fa47bb00ce 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 73e1382d30..7603bb1bdd 100644 --- a/app/views/site/index.html.erb +++ b/app/views/site/index.html.erb @@ -1,33 +1,4 @@ -<% content_for :head do %> - <%= javascript_include_tag "index" %> -<% end %> - -<%= render :partial => 'home_link' %> -<%= render :partial => 'sidebar' %> -<%= render :partial => 'search' %> - - - -
    -
    - -
    -
    - -
    - - - - - - - - -
    <%= t'site.index.license.license_url' %><%= t'site.index.license.project_url' %>
    <%= t'site.index.license.copyright' %>
    -
    - +<% + set_title() + content_for(:content_class) { "overlay-sidebar" } +%> diff --git a/app/views/site/welcome.html.erb b/app/views/site/welcome.html.erb index da775e3393..4edcf361eb 100644 --- a/app/views/site/welcome.html.erb +++ b/app/views/site/welcome.html.erb @@ -3,7 +3,7 @@ <% end %> <% content_for :heading do %> -

    <%= t "welcome_page.title" %>

    +

    <%= t "welcome_page.title" %>

    <% end %>

    <%= t "welcome_page.introduction_html" %>

    @@ -51,7 +51,7 @@

    <%= t "welcome_page.questions.title" %>

    -

    <%= t "welcome_page.questions.paragraph_1_html" %>

    +

    <%= t "welcome_page.questions.paragraph_1_html", :help_url => help_path %>

    @@ -64,4 +64,4 @@

    <%= t "welcome_page.add_a_note.paragraph_1_html" %>

    <%= t "welcome_page.add_a_note.paragraph_2_html", :map_url => root_path %>

    -
    \ No newline at end of file +
    diff --git a/app/views/user/_contact.html.erb b/app/views/user/_contact.html.erb index 9d719b52f5..4811389f12 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 e5cbe22b53..94183ff424 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 31f29eb642..9fc33094e0 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 d472f96b04..062d18fb52 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 fc7b599292..f39bafec73 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 47358b3878..2db9f23662 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -69,12 +69,13 @@ # 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/ast.yml b/config/locales/ast.yml index 0e1258d335..87a4f0c483 100644 --- a/config/locales/ast.yml +++ b/config/locales/ast.yml @@ -216,7 +216,6 @@ ast: hide_areas: Anubrir árees history_for_feature: Historial de %{feature} load_data: Cargar datos - loaded_an_area_with_num_features: "Cargasti un área que contién %{num_features} carauterístiques. Polo xeneral, dellos restoladores nun pueden amosar bien esta cantidá de datos. Normalmente los restoladores funcionen meyor amosando menos de %{max_features} carauterístiques al tiempu: d'otra miente se tornen lentos/dexen de responder. Si tas seguru d'amosar los datos, pues facelo calcando nel botón d'abaxo." loading: Cargando... manually_select: Seleiciona manualmente un área distinta notes_layer_name: Navegar notes diff --git a/config/locales/be-Tarask.yml b/config/locales/be-Tarask.yml index 7f74340c9c..7bc49e4ff1 100644 --- a/config/locales/be-Tarask.yml +++ b/config/locales/be-Tarask.yml @@ -209,7 +209,6 @@ be-Tarask: hide_areas: Схаваць вобласьці history_for_feature: Гісторыя %{feature} load_data: Загрузіць зьвесткі - loaded_an_area_with_num_features: Вы загрузілі мясцовасьць, якая ўтрымлівае %{num_features} аб’ектаў. Увогуле, некаторыя браўзэры ня змогуць апрацаваць такую колькасьць зьвестак. Звычайна найлепшы вынік назіраецца, калі аб’ектаў менш за %{max_features}, пры выкананьні яшчэ нейкіх задачаў браўзэр можа страціць хуткасьць/завіснуць. Калі Вы ўпэўненыя, што жадаеце паказаць гэтыя зьвесткі, націсьніце кнопку ніжэй. loading: Загрузка… manually_select: Выбраць іншы абшар notes_layer_name: Прагляд нататак diff --git a/config/locales/bs.yml b/config/locales/bs.yml index 7066d1a907..8bb89b6442 100644 --- a/config/locales/bs.yml +++ b/config/locales/bs.yml @@ -207,7 +207,6 @@ bs: hide_areas: Sakriti područja history_for_feature: Historija za %{feature} load_data: Učitati podatke - loaded_an_area_with_num_features: "Učitali ste područje koje sadrži %{num_features} značajki. Općenito, neki se web preglednici ne mogu nositi sa prikazom tolike količine podataka. Inače, preglednici najbolje rade kada prikazuju manje od %{max_features} značajki istovremeno: ukoliko radite još nešto, to može usporiti preglednik ili ga zalediti. Ako ste sigurni da želite prikazati ove podtake, možete to učiniti klikom na dugme ispod." loading: Učitavanje... manually_select: Ručno izabrati drukčije područje object_list: diff --git a/config/locales/cs.yml b/config/locales/cs.yml index 15320f3e9a..886ff1c836 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -233,7 +233,6 @@ cs: hide_areas: Schovat oblasti history_for_feature: Historie pro %{feature} load_data: Nahrát data - loaded_an_area_with_num_features: Máte načtenu oblast, která obsahuje %{num_features} prvků. Některé prohlížeče mohou mít potíže při zobrazování takového množství dat. Obecně fungují prohlížeče nejlépe při zobrazování ne více než %{max_features} prvků současně – větší množství může způsobit, že bude prohlížeč reagovat pomalu či vůbec. Pokud jste si jisti, že chcete tato data zobrazit, klikněte na tlačítko níže. loading: Načítá se… manually_select: Ručně vybrat jinou oblast notes_layer_name: Procházet poznámky diff --git a/config/locales/da.yml b/config/locales/da.yml index f74e010805..1bf66fffc7 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -231,7 +231,6 @@ da: hide_areas: Skjul områder history_for_feature: Historik for %{feature} load_data: Indlæs data - loaded_an_area_with_num_features: "Du har indlæst et område som indeholder %{num_features} objekter. Nogle browsere kan have problemer ved håndtering af så meget data. Browsere fungerer generelt bedst med mindre end %{max_features} objekter ad gangen: flere objekter kan gøre at din browser bliver langsom. Hvis du er sikker på, at du vil se alle disse data, så klik på knappen nedenfor." loading: Indlæser... manually_select: Vælg et andet område manuelt notes_layer_name: Gennemse bemærkninger diff --git a/config/locales/de.yml b/config/locales/de.yml index 5e0662e9fd..9bfdd94653 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -246,7 +246,6 @@ de: hide_areas: Flächen ausblenden history_for_feature: Chronik für %{feature} load_data: Daten laden - loaded_an_area_with_num_features: Du hast einen Bereich ausgewählt, der %{num_features} Elemente enthält. Manche Browser werden bei der Verarbeitung einer so großen Datenmenge langsam oder frieren ein (reagieren nicht mehr auf Eingaben). Üblicherweise sollten weniger als %{max_features} Elemente angezeigt werden. Falls du dir sicher bist, dass so viele Elemente laden möchtest, klicke unten auf „Daten laden“. loading: Lade … manually_select: Einen anderen Kartenausschnitt manuell auswählen notes_layer_name: Alle Hinweise anzeigen diff --git a/config/locales/el.yml b/config/locales/el.yml index 845de71f34..503fdfad7c 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -234,7 +234,6 @@ el: hide_areas: Απόκρυψη περιοχών history_for_feature: Ιστορικό για %{feature} load_data: Φόρτωση δεδομένων - loaded_an_area_with_num_features: "Έχετε φορτώσει μια περιοχή που περιέχει %{num_features} χαρακτηριστικά. Γενικά, μερικοί browsers μπορεί να μην αντέχουν να δείξουν τόσα πολλά στοιχεία. Γενικά, οι browsers δουλεύουν καλύτερα δείχνοντας λιγότερα από %{max_features} χαρακτηριστικά τη φορά: με οτιδήποτε άλλο ο browser μπορεί να γίνει αργός ή να μην αντιδρά. Αν είστε σίγουρος ότι θέλετε να δείτε αυτά τα δεδομένα, κάντε κλικ στο παρακάτω κουμπί." loading: Φόρτωση σε εξέλιξη... manually_select: Χειροκίνητη επιλογή διαφορετικής περιοχής notes_layer_name: Περιήγηση Σημειώσεων diff --git a/config/locales/en.yml b/config/locales/en.yml index d7411e997c..003f16fc0a 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:" + title: "Note: %{id}" + 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,15 @@ 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 found." + empty_area: "No changesets in this area." + empty_user: "No changesets by this user." + no_more: "No more changesets found." + no_more_area: "No more changesets in this area." + no_more_user: "No more changesets by this user." + load_more: "Load more" timeout: sorry: "Sorry, the list of changesets you requested took too long to retrieve." diary_entry: @@ -416,6 +298,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" @@ -426,8 +309,7 @@ en: licence: "Licence" export_details: 'OpenStreetMap data is licensed under the Open Data Commons Open Database License (ODbL).' too_large: - heading: "Area Too Large" - body: "This area is too large to be exported as OpenStreetMap XML Data. Please zoom in or select a smaller area, or use one of the following sources for bulk data downloads:" + body: "This area is too large to be exported as OpenStreetMap XML Data. Please zoom in or select a smaller area, or use one of the sources listed below for bulk data downloads." planet: title: "Planet OSM" description: "Regularly-updated copies of the complete OpenStreetMap database" @@ -452,13 +334,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: @@ -999,15 +874,15 @@ en: logo: alt_text: OpenStreetMap logo home: Go to Home Location - logout: Logout - log_in: log in + logout: Log Out + log_in: Log In log_in_tooltip: Log in with an existing account - sign_up: sign up + sign_up: Sign Up + start_mapping: Start Mapping 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 +891,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 a 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 +903,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 +914,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 +1060,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 +1073,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 +1295,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 +2050,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/locales/es.yml b/config/locales/es.yml index f801aa2091..17223fdbdd 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -240,7 +240,6 @@ es: hide_areas: Ocultar áreas history_for_feature: Historial de %{feature} load_data: Cargar datos - loaded_an_area_with_num_features: Has cargado un área que contiene %{num_features} objetos. Por lo general, algunos navegadores de internet no aguantan bien el mostrar esta cantidad de información vectorial. Generalmente, el funcionamiento óptimo se da cuando se muestran menos de %{max_features} objetos al mismo tiempo; de otra manera, tu navegador puede volverse lento o no responder. Si estás seguro de que quieres mostrar todos estos datos, puedes hacerlo pulsando el botón que aparece debajo. loading: Cargando... manually_select: Seleccionar manualmente un área diferente notes_layer_name: Ver notas diff --git a/config/locales/et.yml b/config/locales/et.yml index f6d045da78..8cffe3cbc4 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -200,7 +200,6 @@ et: hide_areas: Peida alad history_for_feature: Omaduse %{feature} ajalugu load_data: Laadi andmed - loaded_an_area_with_num_features: Oled laadinud ala, mis sisaldab %{num_features} objekti. Mõned brauserid ei saa hästi hakkama sellise hulga andmete kuvamisega. Üldiselt suudavad brauserid kuvada korraga kuni %{max_features} objekti. Suurema arvu laadimine võib muuta brauseri aeglaseks või see lakkab üldse toimimast. Kui soovid siiski neid andmeid kuvada, võid seda teha, klõpsates nupul allpool. loading: Laadin andmeid... manually_select: Vali uus ala notes_layer_name: Sirvi märkuseid diff --git a/config/locales/fi.yml b/config/locales/fi.yml index 43f0a94d2c..1393ed1e4e 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -232,7 +232,6 @@ fi: hide_areas: Piilota alueet history_for_feature: Ominaisuuden %{feature} historia load_data: Lataa tiedot - loaded_an_area_with_num_features: Olet ladannut alueen, joka sisältää %{num_features} osiota. Yleensä jotkin selaimet eivät kykene näyttämään tätä määrää dataa. Yleisesti selaimet toimivat parhaiten näyttäessään alle %{max_features} kohdetta kerrallaan. Muussa tapauksessa selain saattaa tulla hitaaksi tai lakata toimimasta kokonaan. Jos olet varma että haluat näyttää tämän datan, voit tehdä niin napsauttamalla alla olevaa painiketta. loading: Ladataan tietoja... manually_select: Rajaa pienempi alue käsin notes_layer_name: Näytä karttailmoitukset diff --git a/config/locales/fur.yml b/config/locales/fur.yml index 68aae02882..ac96a0cd2a 100644 --- a/config/locales/fur.yml +++ b/config/locales/fur.yml @@ -197,7 +197,6 @@ fur: hide_areas: Plate areis history_for_feature: Storic par %{feature} load_data: Cjame i dâts - loaded_an_area_with_num_features: "Tu âs cjamât une aree che e conten %{num_features} carataristichis. In gjenerâl, cualchi sgarfadôr al podarès no rivâ a gjestî ben cheste cuantitât di dâts. I sgarfadôrs par solit a lavorin miôr se a mostrin mancul di %{max_features} carataristichis ae volte: cualsisei altri numar al podarès ralentâ/no fâ plui rispuindi il sgarfadôr. Se tu sês sigûr di volê mostrâ chescj dâts, frache sul boton ca sot." loading: Daûr a cjamâ... manually_select: Sielç a man une aree divierse notes_layer_name: Mostre lis notis diff --git a/config/locales/gl.yml b/config/locales/gl.yml index 4acac9465b..f23573cc0b 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -219,7 +219,6 @@ gl: hide_areas: Agochar as zonas history_for_feature: Historial de %{feature} load_data: Cargar os datos - loaded_an_area_with_num_features: Cargou unha zona que contén %{num_features} funcionalidades. Pode que algúns navegadores teñan problemas para mostrar correctamente esta cantidade de datos. Xeralmente, os navegadores traballan mellor mostrando menos de %{max_features} funcionalidades á vez. Utilizar máis pode provocar que o navegador vaia lento ou non responda. Se está seguro de que quere mostrar estes datos, pode facelo premendo no seguinte botón. loading: Cargando... manually_select: Escoller manualmente unha zona distinta notes_layer_name: Explorar as notas diff --git a/config/locales/he.yml b/config/locales/he.yml index ffd7142985..4cadc97aee 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -229,7 +229,6 @@ he: hide_areas: להסתרת אזורים history_for_feature: ההיסטוריה של %{feature} load_data: טעינת נתונים - loaded_an_area_with_num_features: "האזור שנטען מכיל %{num_features} תכונות. באופן כללי, חלק מהדפדפנים לא יוכלו להתמודד עם הצגה של כזו כמות של נתונים. לרוב, דפדפנים עובדים באופן מיטבי בהצגת פחות מ־%{max_features} תכונות בו־זמנית: ביצוע משימות נוספות עלול לגרום לדפדפן לפעול באופן איטי או להיתקע. אם ברצונך בכל זאת להציג מידע זה, באפשרותך להציג אותו בלחיצה על הכפתור למטה." loading: בטעינה... manually_select: בחירת אזור אחר ידנית notes_layer_name: עיון בהערות diff --git a/config/locales/hu.yml b/config/locales/hu.yml index e9cd5e40fb..a146d201fd 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -227,7 +227,6 @@ hu: hide_areas: Területek elrejtése history_for_feature: "%{feature} előzményei" load_data: Adatok betöltése - loaded_an_area_with_num_features: "Olyan területet töltöttél be, amely %{num_features} elemet tartalmaz. Néhány böngésző lehet, hogy nem birkózik meg ekkora mennyiségű adattal. Általában a böngészők egyszerre legfeljebb %{max_features} elemet tudnak megjeleníteni: minden más esetben a böngésző lelassulhat/nem válaszolhat. Ha biztos vagy benne, hogy meg szeretnéd jeleníteni ezeket az adatokat, megteheted ezt az alábbi gombra kattintva." loading: Betöltés… manually_select: Más terület kézi kijelölése notes_layer_name: Jegyzetek böngészése diff --git a/config/locales/ia.yml b/config/locales/ia.yml index cf37b41f95..80f0ecf864 100644 --- a/config/locales/ia.yml +++ b/config/locales/ia.yml @@ -217,7 +217,6 @@ ia: hide_areas: Celar areas history_for_feature: Historia de %{feature} load_data: Cargar datos - loaded_an_area_with_num_features: Tu ha cargate un area que contine %{num_features} elementos. In general, alcun navigatores del web pote haber problemas in presentar un tal quantitate de datos. Generalmente, un navigator functiona melio monstrante minus de %{max_features} elementos per vice; alteremente, illo pote devenir lente o non responder. Si tu es secur de voler visualisar iste datos, tu pote cliccar super le button a basso. loading: Cargamento... manually_select: Seliger manualmente un altere area notes_layer_name: Percurrer notas diff --git a/config/locales/id.yml b/config/locales/id.yml index 29e0f7c96f..69ff09e895 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -224,7 +224,6 @@ id: hide_areas: Sembunyikan wilayah history_for_feature: Riwayat untuk %{feature} load_data: Memuat Data - loaded_an_area_with_num_features: "Anda telah memuat wilayah yang berisi %{num_features} fitur. Secara umum, beberapa browser mungkin tidak dapat mengatasi dengan baik untuk menampilkan sejumlah data tersebut, browser akan bekerja dengan baik dalam menampilkan data kurang dari %{max_features} fitur pada saat yang sama: lebih daripada itu akan membuat browser anda menjadi lamban/tidak responsif. Jika anda yakin ingin menampilkan data ini, anda dapat melakukannya dengan mengklik tombol di bawah." loading: Memuat... manually_select: Pilih wilayah berbeda secara manual notes_layer_name: Lihat Catatan diff --git a/config/locales/it.yml b/config/locales/it.yml index 83eafa9f19..0e4d7d3fee 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -234,7 +234,6 @@ it: hide_areas: Nascondi le aree history_for_feature: Cronologia per %{feature} load_data: Carica dati - loaded_an_area_with_num_features: "È stata caricata un'area che contiene %{num_features} caratteristiche. In generale, alcuni browser potrebbero non visualizzare correttamente questa quantità di dati. Generalmente i browser lavorano al meglio se si visualizzano meno di %{max_features} caratteristiche alla volta: se si fa qualcos'altro il proprio browser potrebbe diventare lento o non rispondere più. Se si è sicuri di voler visualizzare questi dati, allora si può premere il pulsante sottostante." loading: Caricamento in corso... manually_select: Seleziona manualmente un'area differente notes_layer_name: Mostra le note diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 9a685238d3..7d579ab589 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -227,7 +227,6 @@ ja: hide_areas: 領域を隠す history_for_feature: "%{feature}の履歴" load_data: データの読み込み - loaded_an_area_with_num_features: "%{num_features}件の地物を含む領域を読み込みました。一般に、ブラウザーによっては、この量のデータを表示するとうまく処理できないかもしれません。通常、ブラウザーは一度に%{max_features}件未満の地物を表示させるとうまく動作します。このままでは、ブラウザーが遅くなったり、反応しなくなったりします。それでもこのデータを表示したいならば、以下のボタンをクリックしてください。" loading: 読み込み中... manually_select: ドラッグして別の領域を選択 notes_layer_name: メモを閲覧 diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 27327ff57e..49451a4c0a 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -216,7 +216,6 @@ ko: hide_areas: 지역 숨기기 history_for_feature: "%{feature}의 역사" load_data: 데이터 불러오기 - loaded_an_area_with_num_features: 당신은 특성을 가진 지역 %{num_features}개를 불러왔습니다. 일반적으로, 일부 브라우저에서는 이 데이터 개수를 모두 처리하지 못할 수도 있습니다. 일반적으로, 브라우저들은 대개 특성 %{max_features}개 이하를 처리하여 보여줄 수 있습니다. 그렇지 않은 경우, 브라우저의 속도가 저하되거나 브라우저의 반응이 느려질 수 있습니다. 여전히 이 데이터를 표시하려면, 아래의 버튼을 클릭하세요. loading: 불러오는 중... manually_select: 다른 지역 선택 notes_layer_name: 참고 찾아보기 diff --git a/config/locales/lt.yml b/config/locales/lt.yml index 8541e82bed..3108aaf606 100644 --- a/config/locales/lt.yml +++ b/config/locales/lt.yml @@ -223,7 +223,6 @@ lt: hide_areas: Slėpti sritis history_for_feature: Istorija apie %{feature} load_data: Kraunami duomenys - loaded_an_area_with_num_features: Jūs įkėlėte sritį, kurioje yra %{num_features} elementų. Dažniausiai naršyklės nelabai gerai susitvarko su tokiu duomenų kiekiu. Paprastai naršyklės kur kas geriau susidoroja, kai elementų yra mažiau nei %{max_features} vienu metu. Bet kokie kiti veiksmai gali stipriai sulėtinti naršyklę. Jei tikrai norite žiūrėti šiuos duomenis, spauskite žemiau esantį mygtuką. loading: Kraunama... manually_select: Rankiniu būdu pažymėkite kitą teritoriją notes_layer_name: Peržiūrėti pastabas diff --git a/config/locales/lv.yml b/config/locales/lv.yml index 3ff4a9f5f2..46305d31d9 100644 --- a/config/locales/lv.yml +++ b/config/locales/lv.yml @@ -225,7 +225,6 @@ lv: hide_areas: Paslēpt zonas history_for_feature: Vēsture %{feature} load_data: Ielādēt datus - loaded_an_area_with_num_features: "Jūs esat ielādējis apgabalu, kurš satur %{num_features} iezīmes. Pamatā, daži pārlūki var pārāk labi netikt galā ar šādu lielu datu kvantuma parādīšanu. Parasti, pārlūki tiek galā vislabāk rādot mazāk nekā %{max_features} iezīmes vienlaikus: jebkā cita darīšana tos bremzē. Ja Jūs esat drošs, ka vēlaties attēlot šos datus, Jūs tā varat izdarīt spiežot pogu zemāk." loading: Ielādē… manually_select: Manuāli izvēlēties citu apgabalu notes_layer_name: Pārlūkot Piezīmes diff --git a/config/locales/mk.yml b/config/locales/mk.yml index c188b58b88..24cc0084cf 100644 --- a/config/locales/mk.yml +++ b/config/locales/mk.yml @@ -217,7 +217,6 @@ mk: hide_areas: Скриј подрачја history_for_feature: Историја за %{feature} load_data: Вчитај ги податоците - loaded_an_area_with_num_features: "Вчитавте простор што содржи %{num_features} елементи. Некои прелистувачи не можат да се справат со толку податоци. Начелно, прелистувачите работат најдобро при помалку од %{max_features} елементи наеднаш: ако правите нешто друго прелистувачот ќе ви биде бавен/пасивен. Ако и покрај тоа сакате да се прикажат овие податоци, тогаш стиснете на копчето подолу." loading: Вчитувам... manually_select: Рачно изберете друга површина notes_layer_name: Прелистај белешки diff --git a/config/locales/ms.yml b/config/locales/ms.yml index aad0a7de3d..e62fe56101 100644 --- a/config/locales/ms.yml +++ b/config/locales/ms.yml @@ -211,7 +211,6 @@ ms: hide_areas: Sorokkan kawasan history_for_feature: Sejarah %{feature} load_data: Muatkan Data - loaded_an_area_with_num_features: Anda telah memilih satu kawasan yang mengandungi %{num_features} ciri. Pada umumnya, sesetengah pelayar web tidak mungkin mampu memaparkan sebegini banyak data dengan betul. Lazimnya, pelayar paling berkemampuan apabila memaparkan kurang daripada %{max_features} ciri sekaligus; lebih daripada itu mungkin akan melambatkan pelayar anda atau membuatnya tidak responsif. Jika anda betul-betul ingin memaparkan data ini, anda boleh berbuat demikian dengan mengklik butang di bawah. loading: Memuatkan... manually_select: Pilih kawasan yang lain secara insani notes_layer_name: Semak Imbas Nota diff --git a/config/locales/nb.yml b/config/locales/nb.yml index 4c596ec2e5..13dc001835 100644 --- a/config/locales/nb.yml +++ b/config/locales/nb.yml @@ -228,7 +228,6 @@ nb: hide_areas: Skjul områder history_for_feature: Historikk for %{feature} load_data: Last inn data - loaded_an_area_with_num_features: "Du har lastet et område som inneholder %{num_features} objekter. Noen nettlesere kan få problemer med å håndtere så mye data. Generelt fungerer nettlesere best med mindre enn %{max_features} objekter av gangen: flere objekter kan føre til at nettleseren din blir treg eller fryser helt. Om du er sikker på at du vil se denne informasjonen, kan du gjøre det ved å klikke på knappen under." loading: Laster... manually_select: Velg et annet område manuelt notes_layer_name: Se på merknader diff --git a/config/locales/nl.yml b/config/locales/nl.yml index c2cdc7642f..af983e78be 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -227,7 +227,6 @@ nl: hide_areas: Gebieden verbergen history_for_feature: Geschiedenis voor %{feature} load_data: Gegevens laden - loaded_an_area_with_num_features: U hebt een gebied geladen dat %{num_features} objecten bevat. Sommige browsers kunnen niet goed overweg met zoveel gegevens. Normaal gesproken werken browsers het best met minder dan %{max_features} objecten. Als u er meer weergeeft kan de browser traag worden of niet meer reageren. Als u zeker weet dat u de gegevens wilt weergeven, klik dan op de knop hieronder. loading: Bezig met laden… manually_select: Handmatig een ander gebied selecteren notes_layer_name: Opmerkingen bekijken diff --git a/config/locales/nn.yml b/config/locales/nn.yml index d4f7b4f806..db435a4e51 100644 --- a/config/locales/nn.yml +++ b/config/locales/nn.yml @@ -231,7 +231,6 @@ nn: hide_areas: Skjul områder history_for_feature: Historikk for %{feature} load_data: Last inn data - loaded_an_area_with_num_features: Dette området inneheld %{num_features} objekt. Nokre nettlesarar kan ikkje handtere så mykje data. For å ikkje risikere at nettlesaren låsar seg bør du halde deg til under %{max_features} objekt. Om du er sikker på at du vil sjå informasjonen kan du klikke på knappen nedanfor. loading: Lastar... manually_select: Vel eit anna område manuelt notes_layer_name: Bla gjennom notiser diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 3fa8f1c7c1..8997c63835 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -240,7 +240,6 @@ pl: hide_areas: Ukryj obszary history_for_feature: Historia zmian dla %{feature} load_data: Wczytaj dane - loaded_an_area_with_num_features: Wczytano obszar zawierający %{num_features} obiektów. Niektóre przeglądarki internetowe mogą nie radzić sobie z wyświetleniem tej ilości danych. Na ogół przeglądarki działają najlepiej przy wyświetlaniu mniej niż %{max_features} obiektów jednocześnie, w przeciwnym przypadku przeglądarka może działać powoli lub przestać odpowiadać. Jeśli jesteś pewien, że chcesz wyświetlić dane, kliknij przycisk poniżej. loading: Wczytywanie... manually_select: Ręcznie zaznacz inny obszar notes_layer_name: Przeglądaj uwagi diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index f6fddbcd86..4aed31772e 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -239,7 +239,6 @@ pt-BR: hide_areas: Ocultar áreas history_for_feature: Histórico para %{feature} load_data: Carregar dados - loaded_an_area_with_num_features: "Você carregou uma área que contém %{num_features} pontos. Alguns navegadores podem não conseguir exibir essa quantidade de dados. Geralmente, navegadores trabalham melhor exibindo menos de %{max_features} pontos por vez: acima disso pode deixá-lo lento ou travá-lo. Se você tem certeza que deseja exibir estes dados, clique no botão abaixo." loading: Carregando... manually_select: Selecionar manualmente uma área diferente notes_layer_name: Ver Notas diff --git a/config/locales/pt.yml b/config/locales/pt.yml index b108a9877e..663cd84b52 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -232,7 +232,6 @@ pt: hide_areas: Ocultar áreas history_for_feature: Histórico de %{feature} load_data: Carregar Dados - loaded_an_area_with_num_features: Carregou uma área com %{num_features} elementos. Alguns navegadores de Internet podem ter problemas em mostrar esta quantidade de dados. Geralmente os navegadores funcionam melhor a mostrar até %{max_features} elementos de cada vez. Mais do que isso o navegador poderá ficar muito lento ou até bloquear. Se tem a certeza que quer mostrar esta quantidade de elementos clique no botão seguinte. loading: A carregar… manually_select: Selecionar manualmente uma área diferente notes_layer_name: Ver Erros Reportados diff --git a/config/locales/ro.yml b/config/locales/ro.yml index ea5c2bab82..18982757b5 100644 --- a/config/locales/ro.yml +++ b/config/locales/ro.yml @@ -195,7 +195,6 @@ ro: hide_areas: Ascunde suprafețele history_for_feature: Istoric pentru %{feature} load_data: Încărcare date - loaded_an_area_with_num_features: "Ați încărcat o zonă care conține %{num_features} elemente. În general, unele navigatoare nu sunt capabile să facă față afișării unei asemenea cantități de date. Navigatoarele funcționează cel mai bine atunci când afișează mai puțin de %{max_features} elemente simultan: dacă mai faceți și alte operații cu navigatorul dumneavoastră în paralel veți observa o încetinire / lipsă de răspuns din partea navigatorului. Dacă doriți să afișați aceste date apăsați butonul de mai jos." loading: Se încarcă... manually_select: Selectare manuală a unei alte zone object_list: diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 876a40bfc9..189c2c0565 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -251,7 +251,6 @@ ru: hide_areas: Скрыть области history_for_feature: История %{feature} load_data: Загрузить данные - loaded_an_area_with_num_features: Вы загрузили область, которая содержит %{num_features} объектов. Некоторые браузеры могут не справиться с отображением такого количества данных. Обычно браузеры могут обрабатывать до %{max_features} объектов. Загрузка большего числа может замедлить ваш браузер или привести к его зависанию. Если вы всё равно хотите отобразить эти данные, нажмите на кнопку ниже. loading: Загрузка... manually_select: Выделить другую область notes_layer_name: Просмотр заметок diff --git a/config/locales/sk.yml b/config/locales/sk.yml index d98e5627c2..5596521128 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -226,7 +226,6 @@ sk: hide_areas: Skryť oblasti history_for_feature: História pre %{feature} load_data: Načítať údaje - loaded_an_area_with_num_features: Máte načítanú oblasť, ktorá obsahuje %{num_features} zložiek. Niektoré prehliadače môžu mať problémy so zobrazením takého množstva dát, viac než približne %{max_features} položiek ich môže spomaliť až zablokovať. Pokiaľ ste si istý, že chcete dáta zobraziť, kliknite na tlačítko nižšie. loading: Nahrávanie... manually_select: Manuálne vybrať inú oblasť notes_layer_name: Zobraziť všetky chyby diff --git a/config/locales/sl.yml b/config/locales/sl.yml index 7fe24a9b33..e897cb3bf4 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -225,7 +225,6 @@ sl: hide_areas: Skrij področja history_for_feature: Zgodovina %{feature} load_data: Naloži podatke - loaded_an_area_with_num_features: "Naložili ste področje, ki vsebuje %{num_features} elementov. Nekateri spletni brskalniki ne zmorejo prikaza takšne količine podatkov. Na splošno brskalniki najbolje prikazujejo %{max_features} ali manj elementov hkrati: karkoli drugega lahko upočasni vaš brskalnik ali ga naredi neodzivnega. Če ste prepričani, da želite prikazati vse te podatke, pritisnite na spodnji gumb." loading: Nalaganje ... manually_select: Ročno izberite drugo področje notes_layer_name: Brskanje opomb diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml index 93e018d24d..f9a29d7806 100644 --- a/config/locales/sr-Latn.yml +++ b/config/locales/sr-Latn.yml @@ -215,7 +215,6 @@ sr-Latn: hide_areas: Sakrij područja history_for_feature: Istorija za %{feature} load_data: Učitaj podatke - loaded_an_area_with_num_features: "Učitali ste područje koje sadrži %{num_features} mogućnosti. Neki pregledači se ne mogu nositi s tolikom količinom podataka. Oni najbolje rade kada prikazuju manje od %{max_features} mogućnosti istovremeno: ako radite još nešto, to može usporiti pregledač ili ga zakočiti. Ako ste sigurni da želite da prikažete ove podatke, možete to uraditi klikom na dugme ispod." loading: Učitavam… manually_select: Ručno izaberite drugo područje object_list: diff --git a/config/locales/sr.yml b/config/locales/sr.yml index db5b8a2d47..8f8c5ee253 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -230,7 +230,6 @@ sr: hide_areas: Сакриј подручја history_for_feature: Историја за %{feature} load_data: Учитај податке - loaded_an_area_with_num_features: "Учитали сте подручје које садржи %{num_features} могућности. Неки прегледачи се не могу носити с толиком количином података. Они најбоље раде када приказују мање од %{max_features} могућности истовремено: ако радите још нешто, то може успорити прегледач или га закочити. Ако сте сигурни да желите да прикажете ове податке, можете то урадити кликом на дугме испод." loading: Учитавам… manually_select: Ручно изаберите друго подручје object_list: diff --git a/config/locales/sv.yml b/config/locales/sv.yml index ba874d1da1..3b1cb6f749 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -242,7 +242,6 @@ sv: hide_areas: Göm område history_for_feature: Historik för %{feature} load_data: Ladda data - loaded_an_area_with_num_features: "Du har läst in ett område som innehåller %{num_features} objekt. En del webbläsare klarar inte av hantering av sådana stora mängder data. Vanligtvis arbetar webbläsare bäst när de visar mindre än %{max_features} objekt samtidigt: att göra någonting annat kan få din webbläsare att bli långsam eller sluta att svara. Om du är säker på att du vill visa denna data kan du göra det genom att klicka på knappen nedan." loading: Läser in... manually_select: Välj ett annan område manuellt notes_layer_name: Bläddra bland anteckningar diff --git a/config/locales/tl.yml b/config/locales/tl.yml index b0edff09c7..202b21e434 100644 --- a/config/locales/tl.yml +++ b/config/locales/tl.yml @@ -211,7 +211,6 @@ tl: hide_areas: Itago ang mga lugar history_for_feature: Kasaysayan para sa %{feature} load_data: Ikarga ang Dato - loaded_an_area_with_num_features: "Nagkarga ka ng isang pook na naglalaman ng %{num_features} na mga tampok. Sa pangkalahatan, ilang mga pantingin-tingin ang hindi maaaring makaangkop ng mabuti sa pagpapakita ng ganitong dami ng dato. Sa pangkalahatan, gumagana ng pinakamahusay ang mga pantingin-tingin kapag nagpapakita ng mas kakaunti kaysa %{max_features} na mga tampok: ang paggawa ng ibang mga bagay ay maaaring makagawa sa iyong pantingin-tingin upang bumagal/hindi tumutugon. Kung nakatitiyak kang nais mong ipakita ang ganitong dato, magagawa mo ito sa pamamagitan ng pagpindot sa pindutang nasa ibaba." loading: Ikinakarga... manually_select: Kinakamay na pumili ng iba pang lugar object_list: diff --git a/config/locales/uk.yml b/config/locales/uk.yml index 277cad201d..f1bae23a00 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -236,7 +236,6 @@ uk: hide_areas: Приховати ділянки history_for_feature: Історія %{feature} load_data: Завантажити Дані - loaded_an_area_with_num_features: "Ви завантажили ділянку, яка містить %{num_features} об’єктів. Загалом, деякі оглядачі можуть не впоратися з відображенням такої кількості даних. Зазвичай, оглядачі працюють краще, коли водночас показується не більше %{max_features} об'єктів: якщо ж ви робите інакше, це може спричинити сповільнення чи взагалі відсутність відгуку у вашому оглядачі. Коли ви впевнені, що слід показати ці дані, можете натиснути кнопку нижче." loading: Завантаження… manually_select: Виберіть іншу ділянку notes_layer_name: Огляд нотаток diff --git a/config/locales/vi.yml b/config/locales/vi.yml index 547b561159..86e59e3416 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -219,7 +219,6 @@ vi: hide_areas: Ẩn các khu vực history_for_feature: Lịch sử %{feature} load_data: Tải Dữ liệu - loaded_an_area_with_num_features: Bạn đã tải vùng chứa %{num_features} đối tượng. Một số trình duyệt bị trục trặc khi hiển thị nhiều dữ liệu như thế. Nói chung, các trình duyệt hoạt động tốt với tối đa %{max_features} đối tượng cùng lúc; nếu hơn thì trình duyệt sẽ chậm chạp. Nếu bạn chắc chắn muốn xem dữ liệu này, hãy bấm nút ở dưới. loading: Đang tải… manually_select: Chọn vùng khác thủ công notes_layer_name: Xem các Ghi chú diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 929b0044d6..02604f8422 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -238,7 +238,6 @@ zh-CN: hide_areas: 隐藏区域 history_for_feature: "%{feature}的历史" load_data: 载入数据 - loaded_an_area_with_num_features: 你已经载入一个包含%{num_features}个特征的区域。一般而言,一些浏览器无法正常显示这一数量的数据。通常,浏览器可以较好地显示少于%{max_features}个特征,超过这一数量则会使你的浏览器变慢/无响应。如果你确定你想要显示这些数据,请单击下面的按钮。 loading: 正在载入... manually_select: 手动选择不同的区域 notes_layer_name: 浏览注释 diff --git a/config/routes.rb b/config/routes.rb index 81548af121..bae002b7cc 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -102,23 +102,36 @@ end # Data browsing - match '/browse/start' => 'browse#start', :via => :get - match '/browse/way/:id' => 'browse#way', :via => :get, :id => /\d+/ - 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/history' => 'browse#node_history', :via => :get, :id => /\d+/ - match '/browse/relation/:id' => 'browse#relation', :via => :get, :id => /\d+/ - 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 '/user/:display_name/edits' => 'changeset#list', :via => :get - match '/user/:display_name/edits/feed' => 'changeset#feed', :via => :get, :defaults => { :format => :atom } + match '/way/:id' => 'browse#way', :via => :get, :id => /\d+/, :as => :way + match '/way/:id/history' => 'browse#way_history', :via => :get, :id => /\d+/ + match '/node/:id' => 'browse#node', :via => :get, :id => /\d+/, :as => :node + match '/node/:id/history' => 'browse#node_history', :via => :get, :id => /\d+/ + match '/relation/:id' => 'browse#relation', :via => :get, :id => /\d+/, :as => :relation + match '/relation/:id/history' => 'browse#relation_history', :via => :get, :id => /\d+/ + match '/changeset/:id' => 'browse#changeset', :via => :get, :as => :changeset, :id => /\d+/ + match '/note/:id' => 'browse#note', :via => :get, :id => /\d+/, :as => "browse_note" + match '/note/new' => 'browse#new_note', :via => :get + match '/user/:display_name/history' => 'changeset#list', :via => :get + match '/user/:display_name/history/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 + match '/history/friends' => 'changeset#list', :via => :get, :friends => true, :as => "friend_changesets" + match '/history/nearby' => 'changeset#list', :via => :get, :nearby => true, :as => "nearby_changesets" + + get '/browse/way/:id', :to => redirect('/way/%{id}') + get '/browse/way/:id/history', :to => redirect('/way/%{id}/history') + get '/browse/node/:id', :to => redirect('/node/%{id}') + get '/browse/node/:id/history', :to => redirect('/node/%{id}/history') + get '/browse/relation/:id', :to => redirect('/relation/%{id}') + get '/browse/relation/:id/history', :to => redirect('/relation/%{id}/history') + get '/browse/changeset/:id', :to => redirect('/changeset/%{id}') + get '/browse/note/:id', :to => redirect('/note/%{id}') + get '/user/:display_name/edits', :to => redirect('/user/%{display_name}/history') + get '/user/:display_name/edits/feed', :to => redirect('/user/%{display_name}/history/feed') + get '/browse/friends', :to => redirect('/history/friends') + get '/browse/nearby', :to => redirect('/history/nearby') + 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 +139,11 @@ 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 +228,7 @@ 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 +239,6 @@ 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 e2937c5d84..5c48a5dc78 100644 --- a/test/functional/browse_controller_test.rb +++ b/test/functional/browse_controller_test.rb @@ -8,78 +8,73 @@ 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 }, + { :path => "/node/1", :method => :get }, { :controller => "browse", :action => "node", :id => "1" } ) assert_routing( - { :path => "/browse/node/1/history", :method => :get }, + { :path => "/node/1/history", :method => :get }, { :controller => "browse", :action => "node_history", :id => "1" } ) assert_routing( - { :path => "/browse/way/1", :method => :get }, + { :path => "/way/1", :method => :get }, { :controller => "browse", :action => "way", :id => "1" } ) assert_routing( - { :path => "/browse/way/1/history", :method => :get }, + { :path => "/way/1/history", :method => :get }, { :controller => "browse", :action => "way_history", :id => "1" } ) assert_routing( - { :path => "/browse/relation/1", :method => :get }, + { :path => "/relation/1", :method => :get }, { :controller => "browse", :action => "relation", :id => "1" } ) assert_routing( - { :path => "/browse/relation/1/history", :method => :get }, + { :path => "/relation/1/history", :method => :get }, { :controller => "browse", :action => "relation_history", :id => "1" } ) assert_routing( - { :path => "/browse/changeset/1", :method => :get }, + { :path => "/changeset/1", :method => :get }, { :controller => "browse", :action => "changeset", :id => "1" } ) assert_routing( - { :path => "/browse/note/1", :method => :get }, + { :path => "/note/1", :method => :get }, { :controller => "browse", :action => "note", :id => "1" } ) - end - - def test_start - xhr :get, :start - assert_response :success + assert_routing( + { :path => "/note/new", :method => :get }, + { :controller => "browse", :action => "new_note" } + ) end def test_read_relation - browse_check 'relation', relations(:visible_relation).relation_id + browse_check 'relation', relations(:visible_relation).relation_id, 'browse/feature' end def test_read_relation_history - browse_check 'relation_history', relations(:visible_relation).relation_id + browse_check 'relation_history', relations(:visible_relation).relation_id, 'browse/history' end def test_read_way - browse_check 'way', ways(:visible_way).way_id + browse_check 'way', ways(:visible_way).way_id, 'browse/feature' end def test_read_way_history - browse_check 'way_history', ways(:visible_way).way_id + browse_check 'way_history', ways(:visible_way).way_id, 'browse/history' end def test_read_node - browse_check 'node', nodes(:visible_node).node_id + browse_check 'node', nodes(:visible_node).node_id, 'browse/feature' end def test_read_node_history - browse_check 'node_history', nodes(:visible_node).node_id + browse_check 'node_history', nodes(:visible_node).node_id, 'browse/history' end def test_read_changeset - browse_check 'changeset', changesets(:normal_user_first_change).id + browse_check 'changeset', changesets(:normal_user_first_change).id, 'browse/changeset' end def test_read_note - browse_check 'note', notes(:open_note).id + browse_check 'note', notes(:open_note).id, 'browse/note' end ## @@ -93,41 +88,37 @@ def test_read_note def test_redacted_node_history get :node_history, :id => nodes(:redacted_node_redacted_version).node_id assert_response :success - assert_template 'node_history' + assert_template 'browse/history' # there are 2 revisions of the redacted node, but only one # should be showing details here. - assert_select "body div#content div.browse_details", 2 - assert_select "body div#content div.browse_details[id=1] div.common", 0 - assert_select "body div#content div.browse_details[id=2] div.common", 1 + assert_select ".browse-section", 2 + assert_select ".browse-section.browse-redacted", 1 + assert_select ".browse-section.browse-node", 1 end def test_redacted_way_history get :way_history, :id => ways(:way_with_redacted_versions_v1).way_id assert_response :success - assert_template 'way_history' + assert_template 'browse/history' # there are 4 revisions of the redacted way, but only 2 # should be showing details here. - assert_select "body div#content div.browse_details", 4 - assert_select "body div#content div.browse_details[id=1] div.common", 1 - assert_select "body div#content div.browse_details[id=2] div.common", 0 - assert_select "body div#content div.browse_details[id=3] div.common", 0 - assert_select "body div#content div.browse_details[id=4] div.common", 1 + assert_select ".browse-section", 4 + assert_select ".browse-section.browse-redacted", 2 + assert_select ".browse-section.browse-way", 2 end def test_redacted_relation_history get :relation_history, :id => relations(:relation_with_redacted_versions_v1).relation_id assert_response :success - assert_template 'relation_history' + assert_template 'browse/history' # there are 4 revisions of the redacted relation, but only 2 # should be showing details here. - assert_select "body div#content div.browse_details", 4 - assert_select "body div#content div.browse_details[id=1] div.common", 1 - assert_select "body div#content div.browse_details[id=2] div.common", 0 - assert_select "body div#content div.browse_details[id=3] div.common", 0 - assert_select "body div#content div.browse_details[id=4] div.common", 1 + assert_select ".browse-section", 4 + assert_select ".browse-section.browse-redacted", 2 + assert_select ".browse-section.browse-relation", 2 end private @@ -136,7 +127,7 @@ def test_redacted_relation_history # First we check that when we don't have an id, it will correctly return a 404 # then we check that we get the correct 404 when a non-existant id is passed # then we check that it will get a successful response, when we do pass an id - def browse_check(type, id) + def browse_check(type, id, template) assert_raise ActionController::UrlGenerationError do get type end @@ -145,6 +136,6 @@ def browse_check(type, id) end get type, {:id => id} assert_response :success - assert_template type + assert_template template end end diff --git a/test/functional/changeset_controller_test.rb b/test/functional/changeset_controller_test.rb index 05f2ff569a..0db84a90b8 100644 --- a/test/functional/changeset_controller_test.rb +++ b/test/functional/changeset_controller_test.rb @@ -40,41 +40,29 @@ def test_routes { :controller => "changeset", :action => "query" } ) assert_routing( - { :path => "/user/name/edits", :method => :get }, + { :path => "/user/name/history", :method => :get }, { :controller => "changeset", :action => "list", :display_name => "name" } ) assert_routing( - { :path => "/user/name/edits/feed", :method => :get }, + { :path => "/user/name/history/feed", :method => :get }, { :controller => "changeset", :action => "feed", :display_name => "name", :format => :atom } ) assert_routing( - { :path => "/browse/friends", :method => :get }, + { :path => "/history/friends", :method => :get }, { :controller => "changeset", :action => "list", :friends => true } ) assert_routing( - { :path => "/browse/nearby", :method => :get }, + { :path => "/history/nearby", :method => :get }, { :controller => "changeset", :action => "list", :nearby => true } ) assert_routing( - { :path => "/browse/changesets", :method => :get }, + { :path => "/history", :method => :get }, { :controller => "changeset", :action => "list" } ) assert_routing( - { :path => "/browse/changesets/feed", :method => :get }, + { :path => "/history/feed", :method => :get }, { :controller => "changeset", :action => "feed", :format => :atom } ) - assert_recognizes( - { :controller => "changeset", :action => "list" }, - { :path => "/browse", :method => :get } - ) - assert_recognizes( - { :controller => "changeset", :action => "list" }, - { :path => "/history", :method => :get } - ) - assert_recognizes( - { :controller => "changeset", :action => "feed", :format => :atom }, - { :path => "/history/feed", :method => :get } - ) end # ----------------------- @@ -1728,14 +1716,23 @@ def test_changeset_limits ## # This should display the last 20 changesets closed. def test_list - changesets = Changeset.where("num_changes > 0").order(:created_at => :desc).limit(20) - assert changesets.size <= 20 get :list, {:format => "html"} assert_response :success + assert_template "changeset/history" + assert_select "h2", :text => "Changesets", :count => 1 + + get :list, {:format => "html", :bbox => '-180,-90,90,180'} + assert_response :success assert_template "list" + + changesets = Changeset. + where("num_changes > 0 and min_lon is not null"). + order(:created_at => :desc). + limit(20) + assert changesets.size <= 20 + # Now check that all 20 (or however many were returned) changesets are in the html - assert_select "h1", :text => "Changesets", :count => 1 - assert_select "div[id='changeset_list'] ul", :count => changesets.size + assert_select "li", :count => changesets.size changesets.each do |changeset| # FIXME this test needs rewriting - test for table contents end @@ -1747,7 +1744,7 @@ def test_list_user user = users(:public_user) get :list, {:format => "html", :display_name => user.display_name} assert_response :success - assert_template "changeset/_user" + assert_template "changeset/history" ## FIXME need to add more checks to see which if edits are actually shown if your data is public end @@ -1781,7 +1778,8 @@ def test_feed_user user = users(:public_user) get :feed, {:format => "atom", :display_name => user.display_name} assert_response :success - assert_template "changeset/_user" + assert_template "changeset/list" + assert_equal "application/atom+xml", response.content_type ## FIXME need to add more checks to see which if edits are actually shown if your data is public end diff --git a/test/functional/diary_entry_controller_test.rb b/test/functional/diary_entry_controller_test.rb index 8725def3dd..92d9bcffda 100644 --- a/test/functional/diary_entry_controller_test.rb +++ b/test/functional/diary_entry_controller_test.rb @@ -96,30 +96,21 @@ def test_showing_new_diary_entry #print @response.body #print @response.to_yaml - assert_select "html", :count => 1 do - assert_select "head", :count => 1 do - assert_select "title", :text => /New Diary Entry/, :count => 1 - end - assert_select "body", :count => 1 do - assert_select "div.wrapper", :count => 1 do - assert_select "div.content-heading", :count => 1 do - assert_select "h1", :text => "New Diary Entry", :count => 1 - end - assert_select "div#content", :count => 1 do - # We don't care about the layout, we just care about the form fields - # that are available - assert_select "form[action='/diary/new']", :count => 1 do - assert_select "input[id=diary_entry_title][name='diary_entry[title]']", :count => 1 - assert_select "textarea#diary_entry_body[name='diary_entry[body]']", :count => 1 - assert_select "input#latitude[name='diary_entry[latitude]'][type=text]", :count => 1 - assert_select "input#longitude[name='diary_entry[longitude]'][type=text]", :count => 1 - assert_select "input[name=commit][type=submit][value=Save]", :count => 1 - end - end - end + assert_select "title", :text => /New Diary Entry/, :count => 1 + assert_select "div.content-heading", :count => 1 do + assert_select "h1", :text => "New Diary Entry", :count => 1 + end + assert_select "div#content", :count => 1 do + # We don't care about the layout, we just care about the form fields + # that are available + assert_select "form[action='/diary/new']", :count => 1 do + assert_select "input[id=diary_entry_title][name='diary_entry[title]']", :count => 1 + assert_select "textarea#diary_entry_body[name='diary_entry[body]']", :count => 1 + assert_select "input#latitude[name='diary_entry[latitude]'][type=text]", :count => 1 + assert_select "input#longitude[name='diary_entry[longitude]'][type=text]", :count => 1 + assert_select "input[name=commit][type=submit][value=Save]", :count => 1 end end - end def test_editing_diary_entry @@ -134,46 +125,32 @@ def test_editing_diary_entry # Verify that you get a not found error, when you pass a bogus id get(:edit, {:display_name => entry.user.display_name, :id => 9999}, {'user' => entry.user.id}) assert_response :not_found - assert_select "html", :count => 1 do - assert_select "body", :count => 1 do - assert_select "div.wrapper", :count => 1 do - assert_select "div.content-heading", :count => 1 do - assert_select "h2", :text => "No entry with the id: 9999", :count => 1 - end - end - end + assert_select "div.content-heading", :count => 1 do + assert_select "h2", :text => "No entry with the id: 9999", :count => 1 end - + # Now pass the id, and check that you can edit it, when using the same # user as the person who created the entry get(:edit, {:display_name => entry.user.display_name, :id => entry.id}, {'user' => entry.user.id}) assert_response :success - assert_select "html", :count => 1 do - assert_select "head", :count => 1 do - assert_select "title", :text => /Edit diary entry/, :count => 1 - end - assert_select "body", :count => 1 do - assert_select "div.wrapper", :count => 1 do - assert_select "div.content-heading", :count => 1 do - assert_select "h1", :text => /Edit diary entry/, :count => 1 - end - assert_select "div#content", :count => 1 do - assert_select "form[action='/user/#{entry.user.display_name}/diary/#{entry.id}/edit'][method=post]", :count => 1 do - assert_select "input#diary_entry_title[name='diary_entry[title]'][value='#{entry.title}']", :count => 1 - assert_select "textarea#diary_entry_body[name='diary_entry[body]']", :text => entry.body, :count => 1 - assert_select "select#diary_entry_language_code", :count => 1 - assert_select "input#latitude[name='diary_entry[latitude]']", :count => 1 - assert_select "input#longitude[name='diary_entry[longitude]']", :count => 1 - assert_select "input[name=commit][type=submit][value=Save]", :count => 1 - assert_select "input[name=commit][type=submit][value=Edit]", :count => 1 - assert_select "input[name=commit][type=submit][value=Preview]", :count => 1 - assert_select "input", :count => 7 - end - end - end + assert_select "title", :text => /Edit diary entry/, :count => 1 + assert_select "div.content-heading", :count => 1 do + assert_select "h1", :text => /Edit diary entry/, :count => 1 + end + assert_select "div#content", :count => 1 do + assert_select "form[action='/user/#{entry.user.display_name}/diary/#{entry.id}/edit'][method=post]", :count => 1 do + assert_select "input#diary_entry_title[name='diary_entry[title]'][value='#{entry.title}']", :count => 1 + assert_select "textarea#diary_entry_body[name='diary_entry[body]']", :text => entry.body, :count => 1 + assert_select "select#diary_entry_language_code", :count => 1 + assert_select "input#latitude[name='diary_entry[latitude]']", :count => 1 + assert_select "input#longitude[name='diary_entry[longitude]']", :count => 1 + assert_select "input[name=commit][type=submit][value=Save]", :count => 1 + assert_select "input[name=commit][type=submit][value=Edit]", :count => 1 + assert_select "input[name=commit][type=submit][value=Preview]", :count => 1 + assert_select "input", :count => 7 end end - + # Now lets see if you can edit the diary entry new_title = "New Title" new_body = "This is a new body for the diary entry" @@ -191,58 +168,40 @@ def test_editing_diary_entry get :view, {:display_name => entry.user.display_name, :id => entry.id}, {'user' => entry.user.id} assert_response :success assert_template 'diary_entry/view' - assert_select "html", :count => 1 do - assert_select "head", :count => 1 do - assert_select "title", :text => /Users' diaries | /, :count => 1 - end - assert_select "body", :count => 1 do - assert_select "div.wrapper", :count => 1 do - assert_select "div.content-heading", :count => 1 do - assert_select "h2", :text => /#{entry.user.display_name}'s diary/, :count => 1 - end - assert_select "div#content", :count => 1 do - assert_select "div.post_heading", :text => /#{new_title}/, :count => 1 - # This next line won't work if the text has been run through the htmlize function - # due to formatting that could be introduced - assert_select "p", :text => /#{new_body}/, :count => 1 - assert_select "abbr[class=geo][title=#{number_with_precision(new_latitude, :precision => 4)}; #{number_with_precision(new_longitude, :precision => 4)}]", :count => 1 - # As we're not logged in, check that you cannot edit - #print @response.body - assert_select "a[href='/user/#{entry.user.display_name}/diary/#{entry.id}/edit']", :text => "Edit this entry", :count => 1 - end - end - end + assert_select "title", :text => /Users' diaries | /, :count => 1 + assert_select "div.content-heading", :count => 1 do + assert_select "h2", :text => /#{entry.user.display_name}'s diary/, :count => 1 + end + assert_select "div#content", :count => 1 do + assert_select "div.post_heading", :text => /#{new_title}/, :count => 1 + # This next line won't work if the text has been run through the htmlize function + # due to formatting that could be introduced + assert_select "p", :text => /#{new_body}/, :count => 1 + assert_select "abbr[class=geo][title=#{number_with_precision(new_latitude, :precision => 4)}; #{number_with_precision(new_longitude, :precision => 4)}]", :count => 1 + # As we're not logged in, check that you cannot edit + #print @response.body + assert_select "a[href='/user/#{entry.user.display_name}/diary/#{entry.id}/edit']", :text => "Edit this entry", :count => 1 end # and when not logged in as the user who wrote the entry get :view, {:display_name => entry.user.display_name, :id => entry.id}, {'user' => entry.user.id} assert_response :success assert_template 'diary_entry/view' - assert_select "html", :count => 1 do - assert_select "head", :count => 1 do - assert_select "title", :text => /Users' diaries | /, :count => 1 - end - assert_select "body", :count => 1 do - assert_select "div.wrapper", :count => 1 do - assert_select "div.content-heading", :count => 1 do - assert_select "h2", :text => /#{users(:normal_user).display_name}'s diary/, :count => 1 - end - assert_select "div#content", :count => 1 do - assert_select "div.post_heading", :text => /#{new_title}/, :count => 1 - # This next line won't work if the text has been run through the htmlize function - # due to formatting that could be introduced - assert_select "p", :text => /#{new_body}/, :count => 1 - assert_select "abbr[class=geo][title=#{number_with_precision(new_latitude, :precision => 4)}; #{number_with_precision(new_longitude, :precision => 4)}]", :count => 1 - # As we're not logged in, check that you cannot edit - assert_select "li[class=hidden show_if_user_#{entry.user.id}]", :count => 1 do - assert_select "a[href='/user/#{entry.user.display_name}/diary/#{entry.id}/edit']", :text => "Edit this entry", :count => 1 - end - end - end + assert_select "title", :text => /Users' diaries | /, :count => 1 + assert_select "div.content-heading", :count => 1 do + assert_select "h2", :text => /#{users(:normal_user).display_name}'s diary/, :count => 1 + end + assert_select "div#content", :count => 1 do + assert_select "div.post_heading", :text => /#{new_title}/, :count => 1 + # This next line won't work if the text has been run through the htmlize function + # due to formatting that could be introduced + assert_select "p", :text => /#{new_body}/, :count => 1 + assert_select "abbr[class=geo][title=#{number_with_precision(new_latitude, :precision => 4)}; #{number_with_precision(new_longitude, :precision => 4)}]", :count => 1 + # As we're not logged in, check that you cannot edit + assert_select "li[class=hidden show_if_user_#{entry.user.id}]", :count => 1 do + assert_select "a[href='/user/#{entry.user.display_name}/diary/#{entry.id}/edit']", :text => "Edit this entry", :count => 1 end end - #print @response.body - end def test_edit_diary_entry_i18n @@ -261,29 +220,21 @@ def test_create_diary_entry # Now try again when logged in get :new, {}, {:user => users(:normal_user).id} assert_response :success - assert_select "html", :count => 1 do - assert_select "head", :count => 1 do - assert_select "title", :text => /New Diary Entry/, :count => 1 - end - assert_select "body", :count => 1 do - assert_select "div.wrapper", :count => 1 do - assert_select "div.content-heading", :count => 1 do - assert_select "h1", :text => /New Diary Entry/, :count => 1 - end - assert_select "div#content", :count => 1 do - assert_select "form[action='/diary/new'][method=post]", :count => 1 do - assert_select "input#diary_entry_title[name='diary_entry[title]']", :count => 1 - assert_select "textarea#diary_entry_body[name='diary_entry[body]']", :text => "", :count => 1 - assert_select "select#diary_entry_language_code", :count => 1 - assert_select "input#latitude[name='diary_entry[latitude]']", :count => 1 - assert_select "input#longitude[name='diary_entry[longitude]']", :count => 1 - assert_select "input[name=commit][type=submit][value=Save]", :count => 1 - assert_select "input[name=commit][type=submit][value=Edit]", :count => 1 - assert_select "input[name=commit][type=submit][value=Preview]", :count => 1 - assert_select "input", :count => 7 - end - end - end + assert_select "title", :text => /New Diary Entry/, :count => 1 + assert_select "div.content-heading", :count => 1 do + assert_select "h1", :text => /New Diary Entry/, :count => 1 + end + assert_select "div#content", :count => 1 do + assert_select "form[action='/diary/new'][method=post]", :count => 1 do + assert_select "input#diary_entry_title[name='diary_entry[title]']", :count => 1 + assert_select "textarea#diary_entry_body[name='diary_entry[body]']", :text => "", :count => 1 + assert_select "select#diary_entry_language_code", :count => 1 + assert_select "input#latitude[name='diary_entry[latitude]']", :count => 1 + assert_select "input#longitude[name='diary_entry[longitude]']", :count => 1 + assert_select "input[name=commit][type=submit][value=Save]", :count => 1 + assert_select "input[name=commit][type=submit][value=Edit]", :count => 1 + assert_select "input[name=commit][type=submit][value=Preview]", :count => 1 + assert_select "input", :count => 7 end end @@ -320,14 +271,8 @@ def test_creating_diary_comment # Verify that you get a not found error, when you pass a bogus id post :comment, {:display_name => entry.user.display_name, :id => 9999}, {:user => users(:public_user).id} assert_response :not_found - assert_select "html", :count => 1 do - assert_select "body", :count => 1 do - assert_select "div.wrapper", :count => 1 do - assert_select "div.content-heading", :count => 1 do - assert_select "h2", :text => "No entry with the id: 9999", :count => 1 - end - end - end + assert_select "div.content-heading", :count => 1 do + assert_select "h2", :text => "No entry with the id: 9999", :count => 1 end # Now try again with the right id diff --git a/test/functional/export_controller_test.rb b/test/functional/export_controller_test.rb index 0e7529b778..d36f0cfd80 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 @@ def test_routes ) 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/test/functional/geocoder_controller_test.rb b/test/functional/geocoder_controller_test.rb index d8eee97d8a..e39bab80b8 100644 --- a/test/functional/geocoder_controller_test.rb +++ b/test/functional/geocoder_controller_test.rb @@ -8,7 +8,7 @@ class GeocoderControllerTest < ActionController::TestCase # test all routes which lead to this controller def test_routes assert_routing( - { :path => "/geocoder/search", :method => :post }, + { :path => "/search", :method => :get }, { :controller => "geocoder", :action => "search" } ) assert_routing( diff --git a/test/functional/message_controller_test.rb b/test/functional/message_controller_test.rb index 77fdfbeb91..45d0a267c4 100644 --- a/test/functional/message_controller_test.rb +++ b/test/functional/message_controller_test.rb @@ -93,7 +93,7 @@ def test_new get :new, :display_name => "non_existent_user" assert_response :not_found assert_template "user/no_such_user" - assert_select "h2", "The user non_existent_user does not exist" + assert_select "h1", "The user non_existent_user does not exist" end ## diff --git a/test/functional/site_controller_test.rb b/test/functional/site_controller_test.rb index 2db756ad12..86a8fe609f 100644 --- a/test/functional/site_controller_test.rb +++ b/test/functional/site_controller_test.rb @@ -40,10 +40,10 @@ def test_routes ) assert_routing( { :path => "/export", :method => :get }, - { :controller => "site", :action => "index", :export => true } + { :controller => "site", :action => "export" } ) assert_recognizes( - { :controller => "site", :action => "index", :export => true, :format => "html" }, + { :controller => "site", :action => "export", :format => "html" }, { :path => "/export.html", :method => :get } ) assert_routing( @@ -74,7 +74,6 @@ def test_index get :index assert_response :success assert_template 'index' - assert_site_partials end def test_index_redirect @@ -122,12 +121,6 @@ def test_offline get :offline assert_response :success assert_template 'offline' - assert_site_partials 0 - end - - def assert_site_partials(count = 1) - assert_template :partial => '_search', :count => count - assert_template :partial => '_sidebar', :count => count end # test the right editor gets used when the user hasn't set a preference diff --git a/test/functional/user_blocks_controller_test.rb b/test/functional/user_blocks_controller_test.rb index 49fb6552ff..d52ff68c4d 100644 --- a/test/functional/user_blocks_controller_test.rb +++ b/test/functional/user_blocks_controller_test.rb @@ -141,13 +141,13 @@ def test_new get :new assert_response :not_found assert_template "user/no_such_user" - assert_select "h2", "The user does not exist" + assert_select "h1", "The user does not exist" # We should get an error if the user doesn't exist get :new, :display_name => "non_existent_user" assert_response :not_found assert_template "user/no_such_user" - assert_select "h2", "The user non_existent_user does not exist" + assert_select "h1", "The user non_existent_user does not exist" end ## @@ -238,13 +238,13 @@ def test_create post :create assert_response :not_found assert_template "user/no_such_user" - assert_select "h2", "The user does not exist" + assert_select "h1", "The user does not exist" # We should get an error if the user doesn't exist post :create, :display_name => "non_existent_user" assert_response :not_found assert_template "user/no_such_user" - assert_select "h2", "The user non_existent_user does not exist" + assert_select "h1", "The user non_existent_user does not exist" end ## @@ -369,7 +369,7 @@ def test_blocks_on get :blocks_on, :display_name => "non_existent_user" assert_response :not_found assert_template "user/no_such_user" - assert_select "h2", "The user non_existent_user does not exist" + assert_select "h1", "The user non_existent_user does not exist" # Check the list of blocks for a user that has never been blocked get :blocks_on, :display_name => users(:normal_user).display_name @@ -407,7 +407,7 @@ def test_blocks_by get :blocks_by, :display_name => "non_existent_user" assert_response :not_found assert_template "user/no_such_user" - assert_select "h2", "The user non_existent_user does not exist" + assert_select "h1", "The user non_existent_user does not exist" # Check the list of blocks given by one moderator get :blocks_by, :display_name => users(:moderator_user).display_name diff --git a/test/functional/user_controller_test.rb b/test/functional/user_controller_test.rb index 66fcef7850..873beccadd 100644 --- a/test/functional/user_controller_test.rb +++ b/test/functional/user_controller_test.rb @@ -397,7 +397,7 @@ def test_user_lost_password end assert_response :success assert_template :lost_password - assert_select "div#error", /^Could not find that email address/ + assert_select ".error", /^Could not find that email address/ # Test resetting using the address as recorded for a user that has an # address which is case insensitively unique @@ -476,7 +476,7 @@ def test_user_update assert_response :success assert_template :account assert_select "div#errorExplanation", false - assert_select "div#notice", /^User information updated successfully/ + assert_select ".notice", /^User information updated successfully/ assert_select "form#accountForm > fieldset > div.form-row > div#user_description_container > div#user_description_content > textarea#user_description", user.description # Changing name to one that exists should fail @@ -484,7 +484,7 @@ def test_user_update post :account, { :display_name => user.display_name, :user => new_attributes }, { "user" => user.id } assert_response :success assert_template :account - assert_select "div#notice", false + assert_select ".notice", false assert_select "div#errorExplanation" assert_select "form#accountForm > fieldset > div.form-row > div.field_with_errors > input#user_display_name" @@ -493,7 +493,7 @@ def test_user_update post :account, { :display_name => user.display_name, :user => new_attributes }, { "user" => user.id } assert_response :success assert_template :account - assert_select "div#notice", false + assert_select ".notice", false assert_select "div#errorExplanation" assert_select "form#accountForm > fieldset > div.form-row > div.field_with_errors > input#user_display_name" @@ -503,7 +503,7 @@ def test_user_update assert_response :success assert_template :account assert_select "div#errorExplanation", false - assert_select "div#notice", /^User information updated successfully/ + assert_select ".notice", /^User information updated successfully/ assert_select "form#accountForm > fieldset > div.form-row > input#user_display_name[value=?]", "new tester" # Record the change of name @@ -514,7 +514,7 @@ def test_user_update post :account, { :display_name => user.display_name, :user => user.attributes }, { "user" => user.id } assert_response :success assert_template :account - assert_select "div#notice", false + assert_select ".notice", false assert_select "div#errorExplanation" assert_select "form#accountForm > fieldset > div.form-row > div.field_with_errors > input#user_new_email" @@ -523,7 +523,7 @@ def test_user_update post :account, { :display_name => user.display_name, :user => user.attributes }, { "user" => user.id } assert_response :success assert_template :account - assert_select "div#notice", false + assert_select ".notice", false assert_select "div#errorExplanation" assert_select "form#accountForm > fieldset > div.form-row > div.field_with_errors > input#user_new_email" @@ -533,7 +533,7 @@ def test_user_update assert_response :success assert_template :account assert_select "div#errorExplanation", false - assert_select "div#notice", /^User information updated successfully/ + assert_select ".notice", /^User information updated successfully/ assert_select "form#accountForm > fieldset > div.form-row > input#user_new_email[value=?]", user.new_email end @@ -548,7 +548,7 @@ def test_user_view_account get :view, {:display_name => "test"} assert_response :success assert_select "div#userinformation" do - assert_select "a[href=/user/test/edits]", 1 + assert_select "a[href^=/user/test/history]", 1 assert_select "a[href=/user/test/traces]", 1 assert_select "a[href=/user/test/diary]", 1 assert_select "a[href=/user/test/diary/comments]", 1 @@ -562,7 +562,7 @@ def test_user_view_account get :view, {:display_name => "blocked"} assert_response :success assert_select "div#userinformation" do - assert_select "a[href=/user/blocked/edits]", 1 + assert_select "a[href^=/user/blocked/history]", 1 assert_select "a[href=/user/blocked/traces]", 1 assert_select "a[href=/user/blocked/diary]", 1 assert_select "a[href=/user/blocked/diary/comments]", 1 @@ -576,7 +576,7 @@ def test_user_view_account get :view, {:display_name => "moderator"} assert_response :success assert_select "div#userinformation" do - assert_select "a[href=/user/moderator/edits]", 1 + assert_select "a[href^=/user/moderator/history]", 1 assert_select "a[href=/user/moderator/traces]", 1 assert_select "a[href=/user/moderator/diary]", 1 assert_select "a[href=/user/moderator/diary/comments]", 1 @@ -593,7 +593,7 @@ def test_user_view_account get :view, {:display_name => "test"} assert_response :success assert_select "div#userinformation" do - assert_select "a[href=/user/test/edits]", 1 + assert_select "a[href^=/user/test/history]", 1 assert_select "a[href=/traces/mine]", 1 assert_select "a[href=/user/test/diary]", 1 assert_select "a[href=/user/test/diary/comments]", 1 @@ -610,7 +610,7 @@ def test_user_view_account get :view, {:display_name => "test"} assert_response :success assert_select "div#userinformation" do - assert_select "a[href=/user/test/edits]", 1 + assert_select "a[href^=/user/test/history]", 1 assert_select "a[href=/user/test/traces]", 1 assert_select "a[href=/user/test/diary]", 1 assert_select "a[href=/user/test/diary/comments]", 1 diff --git a/test/functional/user_roles_controller_test.rb b/test/functional/user_roles_controller_test.rb index e942cd0faf..4e4bd6da72 100644 --- a/test/functional/user_roles_controller_test.rb +++ b/test/functional/user_roles_controller_test.rb @@ -42,7 +42,7 @@ def test_grant end assert_response :not_found assert_template "user/no_such_user" - assert_select "h2", "The user non_existent_user does not exist" + assert_select "h1", "The user non_existent_user does not exist" # Granting a role from a user that already has it should fail assert_no_difference "UserRole.count" do @@ -100,7 +100,7 @@ def test_revoke end assert_response :not_found assert_template "user/no_such_user" - assert_select "h2", "The user non_existent_user does not exist" + assert_select "h1", "The user non_existent_user does not exist" # Removing a role from a user that doesn't have it should fail assert_no_difference "UserRole.count" do diff --git a/test/integration/client_application_test.rb b/test/integration/client_application_test.rb index fd6f5ecfa0..f40a966757 100644 --- a/test/integration/client_application_test.rb +++ b/test/integration/client_application_test.rb @@ -79,27 +79,16 @@ def test_3rd_party_token ## # utility method to make the HTML screening easier to read. def assert_in_heading - assert_select "html:root" do - assert_select "body" do - assert_select "div.wrapper" do - assert_select "div.content-heading" do - yield - end - end - end + assert_select "div.content-heading" do + yield end end ## # utility method to make the HTML screening easier to read. def assert_in_body - assert_select "html:root" do - assert_select "body" do - assert_select "div#content" do - yield - end - end + assert_select "div#content" do + yield end end - end diff --git a/test/integration/redirect_test.rb b/test/integration/redirect_test.rb new file mode 100644 index 0000000000..42199ce4e6 --- /dev/null +++ b/test/integration/redirect_test.rb @@ -0,0 +1,71 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class RedirectTest < ActionDispatch::IntegrationTest + def test_history_redirects + get "/browse" + assert_response :redirect + assert_redirected_to "/history" + + get "/browse/changesets" + assert_response :redirect + assert_redirected_to "/history" + + get "/browse/friends" + assert_response :redirect + assert_redirected_to "/history/friends" + + get "/browse/nearby" + assert_response :redirect + assert_redirected_to "/history/nearby" + + get "/user/name/edits" + assert_response :redirect + assert_redirected_to "/user/name/history" + end + + def test_history_feed_redirects + get "/browse/changesets/feed" + assert_response :redirect + assert_redirected_to "/history/feed" + + get "/user/name/edits/feed" + assert_response :redirect + assert_redirected_to "/user/name/history/feed" + end + + def test_browse_redirects + get "/browse/node/1" + assert_response :redirect + assert_redirected_to "/node/1" + + get "/browse/way/1" + assert_response :redirect + assert_redirected_to "/way/1" + + get "/browse/relation/1" + assert_response :redirect + assert_redirected_to "/relation/1" + + get "/browse/changeset/1" + assert_response :redirect + assert_redirected_to "/changeset/1" + + get "/browse/note/1" + assert_response :redirect + assert_redirected_to "/note/1" + end + + def test_browse_history_redirects + get "/browse/node/1/history" + assert_response :redirect + assert_redirected_to "/node/1/history" + + get "/browse/way/1/history" + assert_response :redirect + assert_redirected_to "/way/1/history" + + get "/browse/relation/1/history" + assert_response :redirect + assert_redirected_to "/relation/1/history" + end +end diff --git a/test/integration/user_diaries_test.rb b/test/integration/user_diaries_test.rb index 79436a7db2..278a68e7b0 100644 --- a/test/integration/user_diaries_test.rb +++ b/test/integration/user_diaries_test.rb @@ -36,21 +36,13 @@ def test_showing_create_diary_entry # functional tests rather than this integration test # There are some things that are specific to the integratio # that need to be tested, which can't be tested in the functional tests - assert_select "html:root" do - assert_select "body" do - assert_select "div.wrapper", :count => 1 do - assert_select "div.content-heading", :count => 1 do - assert_select "h1", "New Diary Entry" - end - assert_select "div#content" do - assert_select "form[action='/diary/new']" do - assert_select "input[id=diary_entry_title]" - end - end - end + assert_select "div.content-heading", :count => 1 do + assert_select "h1", "New Diary Entry" + end + assert_select "div#content" do + assert_select "form[action='/diary/new']" do + assert_select "input[id=diary_entry_title]" end end - - end end diff --git a/test/integration/user_login_test.rb b/test/integration/user_login_test.rb index 1d7e429cff..6d8e3e7e0f 100644 --- a/test/integration/user_login_test.rb +++ b/test/integration/user_login_test.rb @@ -16,17 +16,17 @@ def test_login_email_password_normal follow_redirect! assert_response :success - post '/login', {'username' => user.email, 'password' => "wrong", :referer => "/browse"} + post '/login', {'username' => user.email, 'password' => "wrong", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success assert_template 'login' - post '/login', {'username' => user.email, 'password' => "test", :referer => "/browse"} + post '/login', {'username' => user.email, 'password' => "test", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success - assert_template 'changeset/list' + assert_template 'changeset/history' end def test_login_email_password_normal_upcase @@ -38,13 +38,13 @@ def test_login_email_password_normal_upcase follow_redirect! assert_response :success - post '/login', {'username' => user.email.upcase, 'password' => "wrong", :referer => "/browse"} + post '/login', {'username' => user.email.upcase, 'password' => "wrong", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success assert_template 'login' - post '/login', {'username' => user.email.upcase, 'password' => "test", :referer => "/browse"} + post '/login', {'username' => user.email.upcase, 'password' => "test", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success @@ -60,13 +60,13 @@ def test_login_email_password_normal_titlecase follow_redirect! assert_response :success - post '/login', {'username' => user.email.titlecase, 'password' => "wrong", :referer => "/browse"} + post '/login', {'username' => user.email.titlecase, 'password' => "wrong", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success assert_template 'login' - post '/login', {'username' => user.email.titlecase, 'password' => "test", :referer => "/browse"} + post '/login', {'username' => user.email.titlecase, 'password' => "test", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success @@ -82,17 +82,17 @@ def test_login_email_password_public follow_redirect! assert_response :success - post '/login', {'username' => user.email, 'password' => "wrong", :referer => "/browse"} + post '/login', {'username' => user.email, 'password' => "wrong", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success assert_template 'login' - post '/login', {'username' => user.email, 'password' => "test", :referer => "/browse"} + post '/login', {'username' => user.email, 'password' => "test", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success - assert_template 'changeset/list' + assert_template 'changeset/history' end def test_login_email_password_public_upcase @@ -104,17 +104,17 @@ def test_login_email_password_public_upcase follow_redirect! assert_response :success - post '/login', {'username' => user.email.upcase, 'password' => "wrong", :referer => "/browse"} + post '/login', {'username' => user.email.upcase, 'password' => "wrong", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success assert_template 'login' - post '/login', {'username' => user.email.upcase, 'password' => "test", :referer => "/browse"} + post '/login', {'username' => user.email.upcase, 'password' => "test", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success - assert_template 'changeset/list' + assert_template 'changeset/history' end def test_login_email_password_public_titlecase @@ -126,17 +126,17 @@ def test_login_email_password_public_titlecase follow_redirect! assert_response :success - post '/login', {'username' => user.email.titlecase, 'password' => "wrong", :referer => "/browse"} + post '/login', {'username' => user.email.titlecase, 'password' => "wrong", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success assert_template 'login' - post '/login', {'username' => user.email.titlecase, 'password' => "test", :referer => "/browse"} + post '/login', {'username' => user.email.titlecase, 'password' => "test", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success - assert_template 'changeset/list' + assert_template 'changeset/history' end def test_login_username_password_normal @@ -148,17 +148,17 @@ def test_login_username_password_normal follow_redirect! assert_response :success - post '/login', {'username' => user.display_name, 'password' => "wrong", :referer => "/browse"} + post '/login', {'username' => user.display_name, 'password' => "wrong", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success assert_template 'login' - post '/login', {'username' => user.display_name, 'password' => "test", :referer => "/browse"} + post '/login', {'username' => user.display_name, 'password' => "test", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success - assert_template 'changeset/list' + assert_template 'changeset/history' end def test_login_username_password_normal_upcase @@ -170,13 +170,13 @@ def test_login_username_password_normal_upcase follow_redirect! assert_response :success - post '/login', {'username' => user.display_name.upcase, 'password' => "wrong", :referer => "/browse"} + post '/login', {'username' => user.display_name.upcase, 'password' => "wrong", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success assert_template 'login' - post '/login', {'username' => user.display_name.upcase, 'password' => "test", :referer => "/browse"} + post '/login', {'username' => user.display_name.upcase, 'password' => "test", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success @@ -192,13 +192,13 @@ def test_login_username_password_normal_titlecase follow_redirect! assert_response :success - post '/login', {'username' => user.display_name.titlecase, 'password' => "wrong", :referer => "/browse"} + post '/login', {'username' => user.display_name.titlecase, 'password' => "wrong", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success assert_template 'login' - post '/login', {'username' => user.display_name.titlecase, 'password' => "test", :referer => "/browse"} + post '/login', {'username' => user.display_name.titlecase, 'password' => "test", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success @@ -214,17 +214,17 @@ def test_login_username_password_public follow_redirect! assert_response :success - post '/login', {'username' => user.display_name, 'password' => "wrong", :referer => "/browse"} + post '/login', {'username' => user.display_name, 'password' => "wrong", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success assert_template 'login' - post '/login', {'username' => user.display_name, 'password' => "test", :referer => "/browse"} + post '/login', {'username' => user.display_name, 'password' => "test", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success - assert_template 'changeset/list' + assert_template 'changeset/history' end def test_login_username_password_public_upcase @@ -236,17 +236,17 @@ def test_login_username_password_public_upcase follow_redirect! assert_response :success - post '/login', {'username' => user.display_name.upcase, 'password' => "wrong", :referer => "/browse"} + post '/login', {'username' => user.display_name.upcase, 'password' => "wrong", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success assert_template 'login' - post '/login', {'username' => user.display_name.upcase, 'password' => "test", :referer => "/browse"} + post '/login', {'username' => user.display_name.upcase, 'password' => "test", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success - assert_template 'changeset/list' + assert_template 'changeset/history' end def test_login_username_password_public_titlecase @@ -258,17 +258,17 @@ def test_login_username_password_public_titlecase follow_redirect! assert_response :success - post '/login', {'username' => user.display_name.titlecase, 'password' => "wrong", :referer => "/browse"} + post '/login', {'username' => user.display_name.titlecase, 'password' => "wrong", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success assert_template 'login' - post '/login', {'username' => user.display_name.titlecase, 'password' => "test", :referer => "/browse"} + post '/login', {'username' => user.display_name.titlecase, 'password' => "test", :referer => "/history"} assert_response :redirect follow_redirect! assert_response :success - assert_template 'changeset/list' + assert_template 'changeset/history' end def test_login_openid_success @@ -277,7 +277,7 @@ def test_login_openid_success assert_redirected_to "controller" => "user", "action" => "login", "cookie_test" => "true" follow_redirect! assert_response :success - post '/login', {'openid_url' => "http://localhost:1123/john.doe?openid.success=true", :referer => "/browse"} + post '/login', {'openid_url' => "http://localhost:1123/john.doe?openid.success=true", :referer => "/history"} assert_response :redirect res = openid_request(@response.redirect_url) @@ -286,7 +286,7 @@ def test_login_openid_success assert_response :redirect follow_redirect! assert_response :success - assert_template 'changeset/list' + assert_template 'changeset/history' end def test_login_openid_cancel diff --git a/vendor/assets/javascripts/html5shiv.js b/vendor/assets/javascripts/html5shiv.js new file mode 100644 index 0000000000..94324d7c85 --- /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 fa26f6e2c6..2b66295fc1 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));