# 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'
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)
dalli
deadlock_retry (>= 1.2.0)
dynamic_form
- ejs
htmlentities
http_accept_language (~> 2.0.0)
httpclient
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
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
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"
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"
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
+ <dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
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" />
+ <path
+ inkscape:connector-curvature="0"
+ style="color:#000000;fill:#999999;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="m 205.9375,877.51843 -1,1 0,1 3,3 -3,3 0,1 1,1 1,0 3,-3 3,3 1,0 1,-1 0,-1 -3,-3 3,-3 0,-1 -1,-1 -1,0 -3,3 -3,-3 -1,0 z"
+ id="path3059"
+ inkscape:export-filename="/Users/saman/work_repos/osm-redesign/renders/share-1.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
</g>
</svg>
//= 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');
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 = {
* 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;
});
.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
});
}
-/*
- * 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");
+ });
});
+++ /dev/null
-$(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);
- }
- }
- });
- }
-});
+++ /dev/null
-$(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());
-});
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);
+++ /dev/null
-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);
- });
-});
+++ /dev/null
-$(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);
- });
- });
-});
//= 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 <a href='http://www.opencyclemap.org/' target='_blank'>Andy Allan</a>",
- code: "C",
- keyid: "cyclemap",
- name: I18n.t("javascripts.map.base.cycle_map")
- }),
- new L.OSM.TransportMap({
- attribution: copyright + ". Tiles courtesy of <a href='http://www.opencyclemap.org/' target='_blank'>Andy Allan</a>",
- code: "T",
- keyid: "transportmap",
- name: I18n.t("javascripts.map.base.transport_map")
- }),
- new L.OSM.MapQuestOpen({
- attribution: copyright + ". Tiles courtesy of <a href='http://www.mapquest.com/' target='_blank'>MapQuest</a> <img src='http://developer.mapquest.com/content/osm/mq_logo.png'>",
- code: "Q",
- keyid: "mapquest",
- name: I18n.t("javascripts.map.base.mapquest")
- }),
- new L.OSM.HOT({
- attribution: copyright + ". Tiles courtesy of <a href='http://hot.openstreetmap.org/' target='_blank'>Humanitarian OpenStreetMap Team</a>",
- 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) {
}
});
- 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})
L.OSM.layers({
position: position,
- layers: layers,
+ layers: map.baseLayers,
sidebar: sidebar
}).addTo(map);
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) {
});
}
- 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();
});
}
- 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)));
+ });
+});
-//= 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({
});
dataLayer.isWayArea = function () {
- return !areasHidden && L.OSM.DataLayer.prototype.isWayArea.apply(this, arguments);
+ return false;
};
dataLayer.on("click", function (e) {
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(
+ $("<p class='warning'></p>")
+ .text(I18n.t("browse.start_rjs.loaded_an_area_with_num_features", { num_features: count, max_features: limit }))
+ .append(
+ $("<input type='submit'>")
+ .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(
+ $("<p class='warning'></p>")
+ .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();
/*
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) {
}
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) {
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();
- }
}
-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;
+};
--- /dev/null
+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;
+};
--- /dev/null
+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;
+};
--- /dev/null
+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;
+};
-//= 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({
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() {
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();
- });
- });
}
-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;
+};
.attr('class', 'sidebar_heading')
.appendTo($ui)
.append(
- $('<a>')
+ $('<span>')
.text(I18n.t('javascripts.close'))
- .attr('class', 'sidebar_close')
- .attr('href', '#')
+ .attr('class', 'icon close')
.bind('click', toggle))
.append(
$('<h4>')
if (!button.hasClass('disabled')) {
options.sidebar.togglePane($ui, button);
}
+ $('.leaflet-control .control-button').tooltip('hide');
}
function updateButton() {
.attr('class', 'sidebar_heading')
.appendTo($ui)
.append(
- $('<a>')
+ $('<span>')
.text(I18n.t('javascripts.close'))
- .attr('class', 'sidebar_close')
- .attr('href', '#')
+ .attr('class', 'icon close')
.bind('click', toggle))
.append(
$('<h4>')
.appendTo(item);
var input = $('<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);
$('<p>')
.text(I18n.t('javascripts.map.layers.overlays'))
+ .attr("class", "deemphasize")
.appendTo(overlaySection);
var list = $('<ul>')
.appendTo(overlaySection);
- function addOverlay(layer, name) {
+ function addOverlay(layer, name, maxArea) {
+ var refName = name.split(' ').join('_').toLowerCase();
var item = $('<li>')
+ .attr('class', refName)
+ .tooltip({
+ placement: 'top'
+ })
.appendTo(list);
var label = $('<label>')
} else {
map.removeLayer(layer);
}
+ map.fire('overlaylayerchange', {layer: layer});
});
map.on('layeradd layerremove', function() {
input.prop('checked', map.hasLayer(layer));
});
+
+ map.on('zoomend', function() {
+ var disabled = map.getBounds().getSize() >= maxArea;
+ $(input).prop('disabled', disabled);
+ $(item).attr('class', disabled ? 'disabled' : '');
+ item.attr('data-original-title', disabled ?
+ I18n.t('javascripts.site.' + refName + '_zoom_in_tooltip') : '');
+ });
}
- addOverlay(map.noteLayer, I18n.t('javascripts.map.layers.notes'));
- addOverlay(map.dataLayer, I18n.t('javascripts.map.layers.data'));
+ addOverlay(map.noteLayer, I18n.t('javascripts.map.layers.notes'), OSM.MAX_NOTE_REQUEST_AREA);
+ addOverlay(map.dataLayer, I18n.t('javascripts.map.layers.data'), OSM.MAX_REQUEST_AREA);
}
options.sidebar.addPane($ui);
e.stopPropagation();
e.preventDefault();
options.sidebar.togglePane($ui, button);
+ $('.leaflet-control .control-button').tooltip('hide');
}
return $container[0];
}
});
-L.extend(L.Map.prototype, {
+L.OSM.Map = L.Map.extend({
+ initialize: function(id, options) {
+ L.Map.prototype.initialize.call(this, id, options);
+
+ var copyright = I18n.t('javascripts.map.copyright', {copyright_url: '/copyright'});
+ var donate = I18n.t('javascripts.map.donate_link_text', {donate_url: 'http://donate.openstreetmap.org'});
+
+ this.baseLayers = [
+ new L.OSM.Mapnik({
+ attribution: copyright + " ♥ " + donate,
+ code: "M",
+ keyid: "mapnik",
+ name: I18n.t("javascripts.map.base.standard")
+ }),
+ new L.OSM.CycleMap({
+ attribution: copyright + ". Tiles courtesy of <a href='http://www.opencyclemap.org/' target='_blank'>Andy Allan</a>",
+ code: "C",
+ keyid: "cyclemap",
+ name: I18n.t("javascripts.map.base.cycle_map")
+ }),
+ new L.OSM.TransportMap({
+ attribution: copyright + ". Tiles courtesy of <a href='http://www.opencyclemap.org/' target='_blank'>Andy Allan</a>",
+ code: "T",
+ keyid: "transportmap",
+ name: I18n.t("javascripts.map.base.transport_map")
+ }),
+ new L.OSM.MapQuestOpen({
+ attribution: copyright + ". Tiles courtesy of <a href='http://www.mapquest.com/' target='_blank'>MapQuest</a> <img src='http://developer.mapquest.com/content/osm/mq_logo.png'>",
+ code: "Q",
+ keyid: "mapquest",
+ name: I18n.t("javascripts.map.base.mapquest")
+ }),
+ new L.OSM.HOT({
+ attribution: copyright + ". Tiles courtesy of <a href='http://hot.openstreetmap.org/' target='_blank'>Humanitarian OpenStreetMap Team</a>",
+ 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
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();
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
}
});
};
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);
+ }
+ }
}
});
},
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()
+ }
}
});
}
});
-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]
+ });
+}
.attr('class', 'sidebar_heading')
.appendTo($ui)
.append(
- $('<a>')
+ $('<span>')
.text(I18n.t('javascripts.close'))
- .attr('class', 'sidebar_close')
- .attr('href', '#')
+ .attr('class', 'icon close')
.bind('click', toggle))
.append(
$('<h4>')
update();
options.sidebar.togglePane($ui, button);
+ $('.leaflet-control .control-button').tooltip('hide');
}
function toggleMarker() {
+++ /dev/null
-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]
- });
-}
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;
},
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;
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);
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]);
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);
},
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;
},
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 || '';
}
--- /dev/null
+/*
+ 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;
+};
+++ /dev/null
-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();
- });
-});
+++ /dev/null
-<div class="browse_details">
-
- <h4><%- name %></h4>
- <a class='more-details' href="<%- url %>"><%- I18n.t('browse.start_rjs.object_list.details') %></a>
-
- <ul class="inner12">
- <% for (var key in attributes) { %>
- <li><b><%- key %></b>: <%- attributes[key] %></li>
- <% } %>
- <li> <a href="<%- url %>/history" class="browse_show_history"><%- I18n.t('browse.start_rjs.show_history') %></a></li>
- </ul>
-
-</div>
-
-<a href="#" class="browse_show_list button"><%- I18n.t('browse.start_rjs.object_list.back') %></a>
\ No newline at end of file
+++ /dev/null
-<div class="browse_details">
- <h4><%- I18n.t("browse.start_rjs.history_for_feature", {feature: name}) %></h4>
- <a class='more-details' href="<%- url %>/history"><%- I18n.t('browse.start_rjs.details') %></a>
-
- <ul class="inner12">
- <% for (var i = 0; i < history.length; i++) { %>
- <li><%- I18n.t("browse.start_rjs.edited_by_user_at_timestamp", history[i]) %></li>
- <% } %>
- </ul>
-</div>
+++ /dev/null
-<div>
- <h4 class="browse_heading"><%- I18n.t('browse.start_rjs.object_list.heading') %></h4>
- <div>
- <ul class='inner12'>
- <% for (var i = 0; i < features.length; i++) { %>
- <li><%- features[i].typeName %> <a href="<%- features[i].url %>" data-feature-id="<%- features[i].id %>"><%- features[i].name %></a></li>
- <% } %>
- </ul>
- </div>
-
- <div class='inner12'><a href="<%- url %>" class='button'><%- I18n.t('browse.start_rjs.object_list.api') %></a></div>
-
-</div>
+++ /dev/null
-<div class="note">
- <p><%- I18n.t('javascripts.notes.new.intro') %></p>
- <form action="#">
- <input type="hidden" name="lon">
- <input type="hidden" name="lat">
- <textarea class="comment" name="text" cols="40" rows="10"></textarea>
- <br/>
- <div class="buttons clearfix">
- <input type="submit" name="add" value="<%- I18n.t('javascripts.notes.new.add') %>" disabled="1">
- </div>
- </form>
-</div>
+++ /dev/null
-<div class="note">
- <a class="icon link permalink deemphasize" href="/?note=<%- note.id %>"><span><%- I18n.t('javascripts.notes.show.permalink', { id: note.id }) %></span></a>
- <% if (note.comments.some(function (comment) { return !comment.user })) { %>
- <small class="warning"><%- I18n.t('javascripts.notes.show.anonymous_warning') %></small>
- <% } %>
- <% note.comments.forEach(function (comment) { %>
- <div>
- <small class="deemphasize">
- <% 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)
- }) %>
- <% } %>
- </small>
- <div class="comment_body"><%= comment.html %></div>
- </div>
- <% }) %>
- <% if (note.status == "open") { %>
- <form action="#">
- <textarea class="comment" name="text" cols="40" rows="5"></textarea>
- <div class="buttons clearfix">
- <input type="submit" name="hide" value="<%- I18n.t('javascripts.notes.show.hide') %>" class="hide_unless_moderator deemphasize" data-method="DELETE" data-url="<%- note.url %>">
- <input type="submit" name="close" value="<%- I18n.t('javascripts.notes.show.resolve') %>" class="hide_unless_logged_in" data-method="POST" data-url="<%- note.close_url %>">
- <input type="submit" name="comment" value="<%- I18n.t('javascripts.notes.show.comment') %>" data-method="POST" data-url="<%- note.comment_url %>" disabled="1">
- </div>
- </form>
- <% } else { %>
- <form action="#">
- <input type="hidden" name="text" value="">
- <div class="buttons clearfix">
- <input type="submit" name="hide" value="<%- I18n.t('javascripts.notes.show.hide') %>" class="hide_unless_moderator deemphasize" data-method="DELETE" data-url="<%- note.url %>">
- <input type="submit" name="reopen" value="<%- I18n.t('javascripts.notes.show.reactivate') %>" class="hide_unless_logged_in" data-method="POST" data-url="<%- note.reopen_url %>">
- </div>
- </form>
- <% } %>
-</div>
+//= 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 {
$('.start-mapping').attr('href', url);
- } else if (navigator.geolocation) {
+ } else {
function geoSuccess(position) {
window.location = '/edit' + OSM.formatHash({
zoom: 17,
$('.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';
}
});
/* 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 {
-/* 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 */
cursor: help;
}
+strong {
+ font-weight: bold;
+}
+
/* Micro Clearfix | Details: http://nicolasgallagher.com/micro-clearfix-hack/ */
.clearfix:before,
.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 {
margin: 0px;
padding: 0px;
text-align: left;
+ height: 100%;
}
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 {
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%;
margin-right: $lineheight/4;
}
+.red { color: $red; }
+
/* Rules for icons */
.icon {
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; }
.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; }
/* Rules for links */
a {
- color: #00f;
+ color: #24d;
text-decoration: none;
+ -webkit-appearance: none;
+ outline: 0;
&:hover {
text-decoration: underline;
}
line-height: $lineheight;
}
th {
- font-weight: bold;
+ font-weight: 600;
vertical-align: top;
}
td {
}
}
-/* 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 22px 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;
}
}
-/* 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 */
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;
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; }
}
}
}
}
-.leaflet-top.leaflet-right {
+.leaflet-top {
top: $lineheight/2 !important;
.leaflet-control {
margin-right: 0px !important;
-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 {
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;
}
}
}
}
-/* 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;
}
}
-.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;
}
}
.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;
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 */
}
.user-view {
+ // Silly exception; remove when user page is redesigned.
+ .content-inner {
+ max-width: none;
+ }
p#no_home_location {
margin: $lineheight;
}
/* 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 {
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 {
background: darken($lightblue, $hovercolor);
}
}
-
- .form-row {
- margin: auto;
- max-width: 370px;
- }
}
/* Rules for the account settings page */
/* 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 */
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 {
.rsssmall {
position: relative;
- top: 5px;
+ top: 3px;
}
/* General styles for action lists / subnavs / pager navs */
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;
margin-right: 0px;
}
}
- .dropdown-menu {
- left: auto;
- right: 0;
- }
+}
+
+div.secondary-actions {
+ padding: 10px;
+ text-align: center;
}
/* Utility for managing inner content areas */
float: left;
border-radius: 0;
margin:0;
- min-width: 100px;
+ min-width: 75px;
max-width: 180px;
border-right:1px solid white;
text-overflow: ellipsis;
*[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;
}
}
}
}
-/* 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 {
.dropdown-menu {
position: absolute;
top: 100%;
- left: 0;
+ left: -1px;
z-index: 1000;
display: none;
float: left;
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);
.dropdown-submenu:focus > a {
color: #ffffff;
text-decoration: none;
- background-color: #0081c2;
+ background-color: $green;
}
.dropdown-menu > .active > a,
.dropdown-menu > .active > a:focus {
color: #ffffff;
text-decoration: none;
- background-color: #0081c2;
+ background-color: $green;
outline: 0;
}
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;
+ }
+}
+
--- /dev/null
+/* 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;
-#small-title,
-#left,
-#greeting,
-#tabnav,
+header,
#sidebar,
#permalink,
.leaflet-control {
-/* 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 {
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 {
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,
display: none;
}
}
+
+.site-about #content .attr h1 {
+ font-size: 28px;
+}
request.body.rewind
end
+ def map_layout
+ request.xhr? ? 'xhr' : 'map'
+ end
+
def preferred_editor
editor = if params[:editor]
params[:editor]
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
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
##
# 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
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)
before_filter :authorize_web
before_filter :set_locale
+ before_filter :require_oauth, :only => [:search]
def search
normalize_params
@sources.push "osm_nominatim"
@sources.push "geonames" if defined?(GEONAMES_USERNAME)
end
+
+ render :layout => map_layout
end
def search_latlon
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]
def key
expires_in 7.days, :public => true
+ render :layout => false
end
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
def welcome
end
+ def help
+ end
+
+ def about
+ end
+
def preview
render :text => RichText.new(params[:format], params[:text]).to_html
end
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 = []
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
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]
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 = [
--- /dev/null
+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
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]}"
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)
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
link_to h(author.display_name), link_options.merge({:controller => "user", :action => "view", :display_name => author.display_name})
end
end
+
end
--- /dev/null
+module TitleHelper
+ def set_title(title = false)
+ response.headers["X-Page-Title"] = t('layouts.project_name.title') + (title ? ' | ' + title : '')
+ @title = title
+ end
+end
+++ /dev/null
-<div class='column-1'>
-
- <div class='browse-section common'>
- <div>
- <h4><%= t 'browse.changeset_details.created_at' %></h4>
- <p><%= l changeset_details.created_at %></p>
- </div>
-
- <div>
- <h4><%= t 'browse.changeset_details.closed_at' %></h4>
- <p><%= l changeset_details.closed_at %></p>
- </div>
-
- <% if changeset_details.user.data_public? %>
- <div>
- <h4><%= t 'browse.changeset_details.belongs_to' %></h4>
- <p><%= link_to h(changeset_details.user.display_name), :controller => "user", :action => "view", :display_name => changeset_details.user.display_name %></p>
- </div>
- <% end %>
- </div>
-
- <%= render :partial => "tag_details", :object => changeset_details %>
-
- <div class='browse-section clearfix'>
- <h4><%= t 'browse.changeset_details.bounding_box' %></h4>
- <% unless changeset_details.has_valid_bbox? %>
- <p><%= t 'browse.changeset_details.no_bounding_box' %></p>
- <% else bbox = changeset_details.bbox.to_unscaled %>
- <div class='bbox'>
- <div class='max_lat'><%=bbox.max_lat -%></div>
- <div class='min_lon'><%=bbox.min_lon -%></div>
- <div class='box'>(<%= 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') %>)</div>
- <div class='max_lon'><%=bbox.max_lon -%></div>
- <div class='min_lat'><%= bbox.min_lat -%></div>
- </div>
- <% end %>
- </div>
-
- <% unless @nodes.empty? %>
- <div class='browse-section clearfix'>
- <h4><%= t 'browse.changeset_details.has_nodes', :count => @node_pages.item_count %></h4>
- <ul>
- <% @nodes.each do |node| %>
- <li><%= link_to h(printable_name(node, true)), { :action => "node", :id => node.node_id.to_s }, :class => link_class('node', node), :title => link_title(node) %></li>
- <% end %>
- </ul>
- </div>
- <%= render :partial => 'paging_nav', :locals => { :pages => @node_pages, :page_param => "node_page"} %>
- <% end %>
-
- <% unless @ways.empty? %>
- <div class='browse-section clearfix'>
- <h4><%= t 'browse.changeset_details.has_ways', :count => @way_pages.item_count %></h4>
- <ul>
- <% @ways.each do |way| %>
- <li><%= link_to h(printable_name(way, true)), { :action => "way", :id => way.way_id.to_s }, :class => link_class('way', way), :title => link_title(way) %></li>
- <% end %>
- <%=
- #render :partial => "containing_relation", :collection => changeset_details.containing_relation_members
- %>
- </ul>
- </div>
- <%= render :partial => 'paging_nav', :locals => { :pages => @way_pages, :page_param => "way_page" } %>
- <% end %>
-
- <% unless @relations.empty? %>
- <div class='browse-section clearfix'>
- <h4><%= t 'browse.changeset_details.has_relations', :count => @relation_pages.item_count %></h4>
- <ul>
- <% @relations.each do |relation| %>
- <li><%= link_to h(printable_name(relation, true)), { :action => "relation", :id => relation.relation_id.to_s }, :class => link_class('relation', relation), :title => link_title(relation) %></li>
- <% end %>
- </ul>
- </div>
- <%= render :partial => 'paging_nav', :locals => { :pages => @relation_pages, :page_param => "relation_page" } %>
- <% end %>
-
-</div>
\ No newline at end of file
-<div class='browse-section common'>
- <div>
- <% if common_details.visible? %>
- <h4><%= t 'browse.common_details.edited_at' %></h4>
- <% else %>
- <h4><%= t 'browse.common_details.deleted_at' %></h4>
- <% end %>
- <p><%= l common_details.timestamp %></p>
- </div>
-
- <% if common_details.changeset.user.data_public? %>
- <div>
- <% if common_details.visible? %>
- <h4><%= t 'browse.common_details.edited_by' %></h4>
- <% else %>
- <h4><%= t 'browse.common_details.deleted_by' %></h4>
- <% end %>
- <p><%= link_to h(common_details.changeset.user.display_name), :controller => "user", :action => "view", :display_name => common_details.changeset.user.display_name %></p>
- </div>
+<h4>
+ <% if common_details.changeset.tags['comment'].present? %>
+ <%= linkify(h(common_details.changeset.tags['comment'])) %>
+ <% else %>
+ <%= t 'browse.no_comment' %>
<% end %>
+</h4>
- <div>
- <h4><%= t 'browse.common_details.version' %></h4>
- <p><%= h(common_details.version) %></p>
- </div>
+<div class="details">
+ <%=
+ 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)
+ %>
+</div>
- <div>
- <h4><%= t 'browse.common_details.in_changeset' %></h4>
- <p><%= link_to common_details.changeset_id, :action => :changeset, :id => common_details.changeset_id %></p>
- </div>
+<div class="details">
+ <%= t 'browse.version' %>
+ #<%= h(common_details.version) %>
+ ·
+ <%= t 'browse.in_changeset' %>
+ #<%= link_to common_details.changeset_id, :action => :changeset, :id => common_details.changeset_id %>
+</div>
- <% if common_details.changeset.tags['comment'].present? %>
- <div>
- <h4><%= t 'browse.common_details.changeset_comment' %></h4>
- <p><%= linkify(h(common_details.changeset.tags['comment'])) %></p>
- </div>
- <% end %>
+<% if @type == "node" %>
+<div class="details geo">
+ 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"}) %>
</div>
-<%= render :partial => "tag_details", :object => common_details %>
+<% end %>
+
+<%= render :partial => "tag_details", :object => common_details.tags %>
+++ /dev/null
-<div id="browse_map" class='clearfix content_map'>
- <% 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 %>
- <span id="loading"><%= t 'browse.map.loading' %></span>
-
- <ul class='secondary-actions clearfix'>
- <li>
- <% 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 -%>
- </li>
- <li>
- <%= render :partial => 'layouts/edit_menu',
- :locals => { :link_text => t("browse.map.edit.area"),
- :link_class => 'bbox' } %>
- </li>
- </ul>
-
- <% unless map.instance_of? Changeset %>
- <ul class='secondary-actions clearfix'>
- <li>
- <%= link_to t("browse.map.larger." + map.class.to_s.downcase),
- root_path,
- :id => "object_larger_map",
- :class => "geolink object" %>
- </li>
- <li>
- <%= render :partial => 'layouts/edit_menu',
- :locals => { :link_text => t("browse.map.edit." + map.class.to_s.downcase),
- :link_class => 'object' } %>
- </li>
- </ul>
- <% end %>
-
- <% else %>
- <%= t 'browse.map.deleted' %>
- <% end %>
-</div>
+++ /dev/null
-<% type = (@next || @prev).class.name.downcase %>
- <ul class='secondary-actions clearfix pager'>
- <% if @prev %>
- <li>
- <%= link_to t('browse.navigation.paging.all.prev', :id => @prev.id.to_s),
- { :id => @prev.id },
- { :title => t("browse.navigation.all.prev_#{type}_tooltip") } %>
- </li>
- <% end %>
- <% if @next %>
- <li>
- <%= link_to t('browse.navigation.paging.all.next', :id => @next.id.to_s),
- { :id => @next.id },
- { :title => t("browse.navigation.all.next_#{type}_tooltip") } %>
- </li>
- <% end %>
- </ul>
- <% if @next_by_user or @prev_by_user %>
- <ul class='secondary-actions pager clearfix'>
- <% if @prev_by_user %>
- <li>
- <%= 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) } %>
- </li>
- <% end %>
- <li>
- <%=
- 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)) }
- %>
- </li>
- <% if @next_by_user %>
- <li>
- <%= 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) } %>
- </li>
- <% end %>
- </ul>
- <% end %>
--- /dev/null
+<% if node.redacted? %>
+ <div class='browse-section browse-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) %>
+ </div>
+<% else %>
+ <div class='browse-section browse-node'>
+ <%= render :partial => "common_details", :object => node %>
+
+ <% unless node.ways.empty? and node.containing_relation_members.empty? %>
+ <h4><%= t 'browse.part_of' %></h4>
+ <ul>
+ <% node.ways.each do |way| %>
+ <li><%= link_to h(printable_name(way)), { :action => "way", :id => way.id.to_s }, :class => link_class('way', way), :title => link_title(way) %></li>
+ <% end %>
+ <%= render :partial => "containing_relation", :collection => node.containing_relation_members %>
+ </ul>
+ <% end %>
+ </div>
+<% end %>
+++ /dev/null
-<div class="browse_details" id="<%= node_details.version %>">
-<% if node_details.redacted? %>
- <div class='browse-section'>
- <%= 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 %>
- </div>
-<% else %>
- <%= render :partial => "common_details", :object => node_details %>
-
- <% if node_details.visible -%>
- <div class='browse-section'>
- <h4><%= t 'browse.node_details.coordinates' %></h4>
- <div class="geo"><%= 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"}) %></div>
- </div>
- <% end -%>
-
- <% unless node_details.ways.empty? and node_details.containing_relation_members.empty? %>
- <div class='browse-section'>
- <h4><%= t 'browse.node_details.part_of' %></h4>
- <ul>
- <% node_details.ways.each do |way| %>
- <li><%= link_to h(printable_name(way)), { :action => "way", :id => way.id.to_s }, :class => link_class('way', way), :title => link_title(way) %></li>
- <% end %>
- <%= render :partial => "containing_relation", :collection => node_details.containing_relation_members %>
- </ul>
- </div>
- <% end %>
-<% end %>
-</div>
-<div>
-<% 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) } %>
+ <span class="paginate">
+ <%= raw pagination_links_each(pages, {}) { |n| link_to(n, page_param => n) } %>
+ </span>
<% end %>
-</div>
\ No newline at end of file
--- /dev/null
+<% if relation.redacted? %>
+ <div class='browse-section browse-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) %><
+ </div>
+<% else %>
+ <div class='browse-section browse-relation'>
+ <%= render :partial => "common_details", :object => relation %>
+
+ <% unless relation.relation_members.empty? %>
+ <h4><%= t'browse.relation.members' %></h4>
+ <ul><%= render :partial => "relation_member", :collection => relation.relation_members %></ul>
+ <% end %>
+
+ <% unless relation.containing_relation_members.empty? %>
+ <h4><%= t'browse.part_of' %></h4>
+ <ul><%= render :partial => "containing_relation", :collection => relation.containing_relation_members %></ul>
+ <% end %>
+ </div>
+<% end %>
+++ /dev/null
-<div class="browse_details" id="<%= relation_details.version %>">
-<% if relation_details.redacted? %>
- <div class='browse-section'>
- <%= 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 %><
- </div>
-<% else %>
- <%= render :partial => "common_details", :object => relation_details %>
-
- <% unless relation_details.relation_members.empty? %>
- <div class='browse-section'>
- <h4><%= t'browse.relation_details.members' %></h4>
- <ul><%= render :partial => "relation_member", :collection => relation_details.relation_members %></ul>
- </div>
- <% end %>
-
- <% unless relation_details.containing_relation_members.empty? %>
- <div class='browse-section'>
- <h4><%= t'browse.relation_details.part_of' %></h4>
- <ul><%= render :partial => "containing_relation", :collection => relation_details.containing_relation_members %></ul>
- </div>
- <% end %>
-<% end %>
-</div>
- <li><%= format_key(tag[0]) %> = <%= format_value(tag[0], tag[1]) %></li>
\ No newline at end of file
+<li class='clearfix'>
+ <span class='browse-tag-k'><%= format_key(tag[0]) %></span>
+ <span class='browse-tag-v'><%= format_value(tag[0], tag[1]) %></span>
+</li>
-<% unless tag_details.tags.empty? %>
- <div class='browse-section'>
- <h4><%= t'browse.tag_details.tags' %></h4>
- <ul><%= render :partial => "tag", :collection => tag_details.tags.sort %></ul>
- </div>
-<% end %>
\ No newline at end of file
+<% unless tag_details.empty? %>
+ <h4><%= t 'browse.tag_details.tags' %></h4>
+ <ul class='browse-tag-list'>
+ <%= render :partial => "tag", :collection => tag_details.sort %>
+ </ul>
+<% end %>
--- /dev/null
+<% if way.redacted? %>
+ <div class='browse-section browse-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) %>
+ </div>
+<% else %>
+ <div class='browse-section browse-way'>
+ <%= render :partial => "common_details", :object => way %>
+
+ <% unless way.way_nodes.empty? %>
+ <h4><%= t'browse.way.nodes' %></h4>
+ <ul>
+ <% way.way_nodes.each do |wn| %>
+ <li>
+ <%= 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 %>
+ </li>
+ <% end %>
+ </ul>
+ <% end %>
+
+ <% unless way.containing_relation_members.empty? %>
+ <h4><%= t'browse.part_of' %></h4>
+ <ul>
+ <%= render :partial => "containing_relation", :collection => way.containing_relation_members %>
+ </ul>
+ <% end %>
+ </div>
+<% end %>
+++ /dev/null
-<div class="browse_details" id="<%= way_details.version %>">
-<% if way_details.redacted? %>
- <div class='browse-section'>
- <%= 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 %>
- </div>
-<% else %>
- <%= render :partial => "common_details", :object => way_details %>
-
- <% unless way_details.way_nodes.empty? %>
- <div class='browse-section'>
- <h4><%= t'browse.way_details.nodes' %></h4>
- <ul>
- <% way_details.way_nodes.each do |wn| %>
- <li>
- <%= 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 %>
- </li>
- <% end %>
- </ul>
- </div>
- <% end %>
-
- <% unless way_details.containing_relation_members.empty? %>
- <div class='browse-section'>
- <h4><%= t'browse.way_details.part_of' %></h4>
- <ul>
- <%= render :partial => "containing_relation", :collection => way_details.containing_relation_members %>
- </ul>
- <% end %>
-<% end %>
-</div>
-<% content_for :head do %>
-<%= stylesheet_link_tag 'browse' %>
-<% end %>
+<% set_title(t('browse.changeset.title', :id => @changeset.id)) %>
-<% content_for :heading do %>
- <h2><%= t 'browse.changeset.changeset', :id => @changeset.id %></h2>
- <ul class='secondary-actions clearfix'>
- <li><%= link_to(t('browse.changeset.changesetxml'), :controller => "changeset", :action => "read") %></li>
- <li><%= link_to(t('browse.changeset.osmchangexml'), :controller => "changeset", :action => "download") %></li>
- </ul>
-<% end %>
+<h2>
+ <a class="geolink" href="<%= root_path %>"><span class="icon close"></span></a>
+ <%= t('browse.changeset.title', :id => @changeset.id) %>
+</h2>
+
+<div class="browse-section">
+ <h4><%= @changeset.tags['comment'].to_s.presence || t('browse.no_comment') %></h4>
+ <div class="details"><%= changeset_details(@changeset) %></div>
+
+ <%= render :partial => "tag_details", :object => @changeset.tags.except('comment') %>
-<%= render :partial => "navigation" %>
+ <% unless @ways.empty? %>
+ <h4>
+ <%= type_and_paginated_count('way', @way_pages) %>
+ <%= render :partial => 'paging_nav', :locals => { :pages => @way_pages, :page_param => "way_page" } %>
+ </h4>
+ <ul>
+ <% @ways.each do |way| %>
+ <li><%= link_to h(printable_name(way, true)), { :action => "way", :id => way.way_id.to_s }, :class => link_class('way', way), :title => link_title(way) %></li>
+ <% end %>
+ </ul>
+ <% end %>
-<% if @changeset.has_valid_bbox? %>
-<%= render :partial => "map", :object => @changeset %>
+ <% unless @relations.empty? %>
+ <h4>
+ <%= type_and_paginated_count('relation', @relation_pages) %>
+ <%= render :partial => 'paging_nav', :locals => { :pages => @relation_pages, :page_param => "relation_page" } %>
+ </h4>
+ <ul>
+ <% @relations.each do |relation| %>
+ <li><%= link_to h(printable_name(relation, true)), { :action => "relation", :id => relation.relation_id.to_s }, :class => link_class('relation', relation), :title => link_title(relation) %></li>
+ <% end %>
+ </ul>
+ <% end %>
+
+ <% unless @nodes.empty? %>
+ <h4>
+ <%= type_and_paginated_count('node', @node_pages) %>
+ <%= render :partial => 'paging_nav', :locals => { :pages => @node_pages, :page_param => "node_page"} %>
+ </h4>
+ <ul>
+ <% @nodes.each do |node| %>
+ <li><%= link_to h(printable_name(node, true)), { :action => "node", :id => node.node_id.to_s }, :class => link_class('node', node), :title => link_title(node) %></li>
+ <% end %>
+ </ul>
+ <% end %>
+</div>
+
+<% if @next_by_user || @prev_by_user %>
+ <div class='secondary-actions'>
+ <% 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 %>
+ </div>
<% end %>
-<%= render :partial => "changeset_details", :object => @changeset %>
\ No newline at end of file
+
+<div class='secondary-actions'>
+ <%= link_to(t('browse.changeset.changesetxml'), :controller => "changeset", :action => "read") %>
+ ·
+ <%= link_to(t('browse.changeset.osmchangexml'), :controller => "changeset", :action => "download") %>
+</div>
--- /dev/null
+<% set_title(t("browse.#{@type}.title", :name => printable_name(@feature))) %>
+
+<h2>
+ <a class="geolink" href="<%= root_path %>"><span class="icon close"></span></a>
+ <%= t("browse.#{@type}.title", :name => printable_name(@feature)) %>
+</h2>
+
+<%= render :partial => @type, :object => @feature %>
+
+<div class='secondary-actions'>
+ <%= link_to(t('browse.download_xml'), :controller => @type, :action => "read") %>
+ ·
+ <%= link_to(t('browse.view_history'), :action => "#{@type}_history") %>
+</div>
--- /dev/null
+<% set_title(t("browse.#{@type}.history_title", :name => printable_name(@feature))) %>
+
+<h2>
+ <a class="geolink" href="<%= root_path %>"><span class="icon close"></span></a>
+ <%= t("browse.#{@type}.history_title", :name => printable_name(@feature)) %>
+</h2>
+
+<%= render :partial => @type, :collection => @feature.send("old_#{@type}s").reverse %>
+
+<div class='secondary-actions'>
+ <%= link_to(t('browse.download_xml'), :controller => "old_#{@type}", :action => "history") %>
+ ·
+ <%= link_to(t('browse.view_details'), :action => @type) %>
+</div>
--- /dev/null
+<% set_title(t "browse.note.new_note") %>
+
+<h2>
+ <a class="geolink" href="<%= root_path %>"><span class="icon close"></span></a>
+ <%= t "browse.note.new_note" %>
+</h2>
+
+<div class="note browse-section">
+ <p class="warning"><%= t('javascripts.notes.new.intro') %></p>
+ <form action="#">
+ <input type="hidden" name="lon">
+ <input type="hidden" name="lat">
+ <textarea class="comment" name="text" cols="40" rows="10"></textarea>
+ <div class="buttons clearfix">
+ <input type="submit" name="add" value="<%= t('javascripts.notes.new.add') %>" disabled="1">
+ </div>
+ </form>
+</div>
+++ /dev/null
-<%
-@name = printable_name @node
-@title = t('browse.node.node') + ' | ' + @name
-%>
-<% content_for :head do %>
-<%= stylesheet_link_tag 'browse' %>
-<% end %>
-
-<% content_for :heading do %>
- <h2><%= t'browse.node.node_title', :node_name => @name %></h2>
- <ul class='secondary-actions clearfix'>
- <li><%= link_to(t('browse.node.download_xml'), :controller => "node", :action => "read") %></li>
- <li><%= link_to(t('browse.node.view_history'), :action => "node_history") %></li>
- <% if @node.visible -%>
- <li><%= link_to(t('browse.node.edit'), :controller => "site", :action => "edit", :lat => @node.lat, :lon => @node.lon, :zoom => 18, :node => @node.id) %></li>
- <% end -%>
- </ul>
-<% end %>
-<%= render :partial => "navigation" %>
-
-<% if @node.visible -%>
-<%= render :partial => "map", :object => @node %>
-<% end -%>
-
-<div class='column-1'>
- <%= render :partial => "node_details", :object => @node %>
-</div>
\ No newline at end of file
+++ /dev/null
-<%
-@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 %>
- <h2><%= raw t'browse.node_history.node_history_title', :node_name => link_to(h(@name), :action => "node", :id => @node.id) %></h2>
- <ul class='secondary-actions clearfix'>
- <li><%= link_to(t('browse.node_history.download_xml'), :controller => "old_node", :action => "history") %></li>
- <li><%= link_to(t('browse.node_history.view_details'), :action => "node") %></li>
- </ul>
-<% end %>
-
-<% if @node.visible -%>
- <%= render :partial => "map", :object => @node %>
-<% end -%>
-
-<div class='column-1'>
- <% @node.old_nodes.reverse.each do |node| %>
- <%= render :partial => "node_details", :object => node %>
- <% end %>
-</div>
'changeset' => I18n.t('browse.not_found.type.changeset'),
};
%>
-<p><%= t'browse.not_found.sorry', :type=> browse_not_found_type[@type] , :id => params[:id] %></p>
+
+<h2>
+ <a class="geolink" href="<%= root_path %>"><span class="icon close"></span></a>
+ <%= t'browse.not_found.sorry', :type=> browse_not_found_type[@type] , :id => params[:id] %></h2>
-<% content_for :head do %>
-<%= stylesheet_link_tag 'browse' %>
-<% end %>
+<% set_title(t('browse.note.title', :id => @note.id)) %>
-<% content_for :heading do %>
- <h2>
- <%= image_tag "#{@note.status}_note_marker.png", :alt => @note.status %>
- <%= t "browse.note.#{@note.status}_title", :note_name => @note.id %>
- </h2>
-<% end %>
+<h2>
+ <a class="geolink" href="<%= root_path %>"><span class="icon close"></span></a>
+ <%= t "browse.note.#{@note.status}_title", :note_name => @note.id %>
+</h2>
-<%= render :partial => "navigation" %>
-
-<%= render :partial => "map", :object => @note %>
-
-<div class='column-1'>
-
- <% if @note.comments.find { |comment| comment.author.nil? } -%>
- <div class='browse-section common'>
- <p class="warning"><%= t "javascripts.notes.show.anonymous_warning" %></p>
+<div class="browse-section">
+ <h4><%= t('browse.note.mine.description') %></h4>
+ <div class="note-description">
+ <%= h(@note.comments.first.body.to_html) %>
</div>
- <% end -%>
-
- <div class='browse-section common'>
- <div>
- <h4><%= t "browse.note.opened" %></h4>
- <p><%= note_event(@note.created_at, @note.author) %></p>
- </div>
+ <div class="details" data-coordinates="<%= @note.lat %>,<%= @note.lon %>" data-status="<%= @note.status %>">
+ <%= note_event('open', @note.created_at, @note.author) %>
<% if @note.status == "closed" %>
- <div>
- <h4><%= t "browse.note.closed" %></h4>
- <p><%= note_event(@note.closed_at, @note.comments.last.author) %></p>
- </div>
- <% elsif @note.comments.length > 1 %>
- <div>
- <h4><%= t "browse.note.last_modified" %></h4>
- <p><%= note_event(@note.updated_at, @note.comments.last.author) %></p>
- </div>
+ <br/>
+ <%= note_event(@note.status, @note.closed_at, @note.comments.last.author) %>
<% end %>
-
- <div id="c<%= @note.comments.first.id %>">
- <h4><%= t "browse.note.description" %></h4>
- <p><%= h(@note.comments.first.body.to_html) %></p>
- </div>
-
- <div>
- <h4><%= t "browse.node_details.coordinates" %></h4>
- <p class="geo"><%= link_to ("<span class='latitude'>#{number_with_delimiter(@note.lat)}</span>, <span class='longitude'>#{number_with_delimiter(@note.lon)}</span>".html_safe), {:controller => 'site', :action => 'index', :lat => h(@note.lat), :lon => h(@note.lon), :zoom => "18"} %></p>
- </div>
</div>
+ <% if @note.comments.find { |comment| comment.author.nil? } -%>
+ <p class='warning'><%= t "javascripts.notes.show.anonymous_warning" %></p>
+ <% end -%>
+
<% if @note.comments.length > 1 %>
- <div class='browse-section clearfix'>
- <h4><%= t "browse.note.comments" %></h4>
+ <div class='note-comments'>
<ul>
<% @note.comments[1..-1].each do |comment| %>
<li id="c<%= comment.id %>">
+ <small class='deemphasize'><%= note_event(comment.event, comment.created_at, comment.author) %></small>
<%= comment.body.to_html %>
- <small class="deemphasize"><%= note_event(comment.created_at, comment.author) %></small>
</li>
<% end %>
</ul>
</div>
<% end %>
+ <% if @note.status == "open" %>
+ <form action="#">
+ <textarea class="comment" name="text" cols="40" rows="5"></textarea>
+ <div class="buttons clearfix">
+ <input type="submit" name="hide" value="<%= t('javascripts.notes.show.hide') %>" class="hide_unless_moderator deemphasize" data-note-id="<%= @note.id %>" data-method="DELETE" data-url="<%= note_url(@note, 'json') %>">
+ <input type="submit" name="close" value="<%= t('javascripts.notes.show.resolve') %>" class="hide_unless_logged_in" data-note-id="<%= @note.id %>" data-method="POST" data-url="<%= close_note_url(@note, 'json') %>">
+ <input type="submit" name="comment" value="<%= t('javascripts.notes.show.comment') %>" data-note-id="<%= @note.id %>" data-method="POST" data-url="<%= comment_note_url(@note, 'json') %>" disabled="1">
+ </div>
+ </form>
+ <% else %>
+ <form action="#">
+ <input type="hidden" name="text" value="">
+ <div class="buttons clearfix">
+ <input type="submit" name="hide" value="<%= t('javascripts.notes.show.hide') %>" class="hide_unless_moderator deemphasize" data-note-id="<%= @note.id %>" data-method="DELETE" data-url="<%= note_url(@note, 'json') %>">
+ <input type="submit" name="reopen" value="<%= t('javascripts.notes.show.reactivate') %>" class="hide_unless_logged_in" data-note-id="<%= @note.id %>" data-method="POST" data-url="<%= reopen_note_url(@note, 'json') %>">
+ </div>
+ </form>
+ <% end %>
</div>
+++ /dev/null
-<%
-@name = printable_name @relation
-@title = t('browse.relation.relation') + ' | ' + @name
-%>
-<% content_for :head do %>
-<%= stylesheet_link_tag 'browse' %>
-<% end %>
-
-<% content_for :heading do %>
- <h2><%= t'browse.relation.relation_title', :relation_name => @name %></h2>
- <ul class='secondary-actions clearfix'>
- <li><%= link_to(t('browse.relation.download_xml'), :controller => "relation", :action => "read") %></li>
- <li><%= link_to(t('browse.relation.view_history'), :action => "relation_history") %></li>
- </ul>
-<% end %>
-<%= render :partial => "navigation" %>
-<%= render :partial => "map", :object => @relation %>
-
-<div class='column-1'>
- <%= render :partial => "relation_details", :object => @relation %>
-</div>
\ No newline at end of file
+++ /dev/null
-<%
-@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 %>
- <h2><%= raw t'browse.relation_history.relation_history_title', :relation_name => link_to(h(@name), :action => "relation", :id => @relation.id) %></h2>
- <ul class='secondary-actions clearfix'>
- <li><%= link_to(t('browse.relation_history.download_xml'), :controller => "old_relation", :action => "history") %></li>
- <li><%= link_to(t('browse.relation_history.view_details'), :action => "relation") %></li>
- </ul>
-<% end %>
-
-<%= render :partial => "map", :object => @relation %>
-<div class='column-1'>
-<% @relation.old_relations.reverse.each do |relation| %>
- <%= render :partial => "relation_details", :object => relation %>
-<% end %>
-</div>
\ No newline at end of file
+++ /dev/null
-<div id="browse_controls" class='inner12'>
- <a id="browse_filter_toggle" class="button" href="#"><%= t'browse.start_rjs.manually_select' %></a>
- <a id="browse_hide_areas_box" class="button" href="#"><%= t'browse.start_rjs.hide_areas' %></a>
-</div>
-<div id="browse_status" class='inner12'></div>
-<div id="browse_content"></div>
+++ /dev/null
-<%
-@name = printable_name @way
-@title = t('browse.way.way') + ' | ' + @name
-%>
-<% content_for :head do %>
-<%= stylesheet_link_tag 'browse' %>
-<% end %>
-
-<% content_for :heading do %>
- <h2><%= t'browse.way.way_title', :way_name => @name %></h2>
- <ul class='secondary-actions clearfix'>
- <li><%= link_to(t('browse.way.download_xml'), :controller => "way", :action => "read") %></li>
- <li><%= link_to(t('browse.way.view_history'), :action => "way_history") %></li>
- <li><%= link_to(t('browse.way.edit'), :controller => "site", :action => "edit", :way => @way.id) %></li>
- </ul>
-<% end %>
-
-<%= render :partial => "navigation" %>
-<%= render :partial => "map", :object => @way %>
-
-<div class='column-1'>
- <%= render :partial => "way_details", :object => @way %>
-</div>
\ No newline at end of file
+++ /dev/null
-<%
-@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 %>
- <h2><%= raw t'browse.way_history.way_history_title', :way_name => link_to(h(@name), :action => "way", :id => @way.id) %></h2>
- <ul class='secondary-actions clearfix'>
- <li><%= link_to(t('browse.way_history.download_xml'), :controller => "old_way", :action => "history") %></li>
- <li><%= link_to(t('browse.way_history.view_details'), :action => "way") %></li>
- </ul>
-<% end %>
-
-<%= render :partial => "map", :object => @way %>
-<div class='column-1'>
-<% @way.old_ways.reverse.each do |way| %>
- <%= render :partial => "way_details", :object => way %>
-<% end %>
-</div>
\ No newline at end of file
+++ /dev/null
-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"))
+++ /dev/null
-<%= 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" %>
end
%>
-<%= content_tag "ul", :class => 'changeset_item', :id => "changeset_#{changeset.id}", :data => {:changeset => changeset_data} do %>
- <li>
-
- <span class="changeset_id">
- <%=
- link_to(changeset.id,
- {:controller => 'browse', :action => 'changeset', :id => changeset.id},
- {:title => t('changeset.changeset.view_changeset_details')})
- %>
- </span>
-
- <span class='date'>
- <% if changeset.closed_at > DateTime.now %> <%= t'changeset.changeset.still_editing' %>
- <% else %><%= l changeset.closed_at, :format => :long %><% end %>
- </span>
-
- <%if showusername %>
- <span class="user">
- <% if changeset.user.data_public? %>
- <%= link_to h(changeset.user.display_name), :controller => "changeset", :action => "list", :display_name => changeset.user.display_name %>
- <% else %>
- <i><%= t'changeset.changeset.anonymous' %></i>
- <% end %>
- </span>
- <% end %>
- </li>
-
- <li class="comment deemphasize">
- <% if changeset.tags['comment'].to_s != '' %>
- <%= linkify(h(changeset.tags['comment'])) %>
- <% else %>
- <%= t'changeset.changeset.no_comment' %>
- <% end %>
- </li>
-
+<%= content_tag "li", :id => "changeset_#{changeset.id}", :data => {:changeset => changeset_data} do %>
+ <h4>
+ <a class="changeset_id" href="<%= changeset_path(changeset.id) %>">
+ <% if changeset.tags['comment'].to_s != '' %>
+ <%= linkify(h(changeset.tags['comment'])) %>
+ <% else %>
+ <%= t 'browse.no_comment' %>
+ <% end %>
+ </a>
+ </h4>
+ <div class="details">
+ <%= changeset_details(changeset) %>
+ ·
+ #<%= changeset.id %>
+ </div>
<% end %>
+++ /dev/null
-<ul class='secondary-actions pager clearfix'>
- <% if @page > 1 %>
- <li><%= link_to t('changeset.changeset_paging_nav.previous'), params.merge({ :page => @page - 1 }) %></li>
- <% else %>
- <li><%= t('changeset.changeset_paging_nav.previous') %></li>
- <% end %>
-
- <li><%= t('changeset.changeset_paging_nav.showing_page', :page => @page) %></li>
-
- <% if @edits.size < @page_size %>
- <li><%= t('changeset.changeset_paging_nav.next') %></li>
- <% else %>
- <li><%= link_to t('changeset.changeset_paging_nav.next'), params.merge({ :page => @page + 1 }) %></li>
- <% end %>
-</ul>
\ No newline at end of file
+++ /dev/null
-<% showusername = true if showusername.nil? %>
-<div id="changeset_list">
- <%= render :partial => 'changeset', :locals => {:showusername => showusername}, :collection => @edits unless @edits.nil? %>
-</div>
+++ /dev/null
-<div id="changeset_list_map">
-</div>
+++ /dev/null
-<%= link_to user.display_name, :controller => "user", :action => "view", :display_name => user.display_name %>
--- /dev/null
+<% 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
+%>
+
+<h2>
+ <a class="geolink" href="<%= root_path %>"><span class="icon close"></span></a>
+ <%= @heading %>
+</h2>
+
+<div class="changesets">
+ <%= image_tag "searching.gif", :class => "loader" %>
+</div>
"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"
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
-<% content_for :head do -%>
- <%= javascript_include_tag "changeset" %>
-<% end -%>
-
-<% content_for :heading do %>
-
- <h1><%= @heading %></h1>
- <ul class='secondary-actions clearfix'>
- <li><%= raw(@description) %></li>
- <% unless params[:friends] or params[:nearby] -%>
- <li><%= atom_link_to params.merge({ :page => nil, :action => :feed }) %></li>
- <% end -%>
- </ul>
-
-<% end %>
-
-<%= render :partial => 'changeset_paging_nav' %>
-
-<% if @edits.size > 0 %>
- <div id='changeset_list_map_wrapper'>
- <%= render :partial => 'map' %>
- </div>
- <div class='column-1'>
- <%= render :partial => 'changesets', :locals => { :showusername => !params.has_key?(:display_name) } %>
+<% if @edits.present? %>
+ <ol class="changesets">
+ <%= render :partial => 'changeset', :collection => @edits %>
+ </ol>
+ <div class="changeset_more">
+ <%= 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;" %>
</div>
- <%= render :partial => 'changeset_paging_nav' %>
-<% elsif @user and @user.display_name == params[:display_name] %>
- <h4><%= t('changeset.list.empty_user_html') %></h4>
+<% elsif params[:bbox] %>
+ <div class="inner22"><%= t(params[:max_id] ? 'changeset.list.no_more_area' : 'changeset.list.empty_area') %></div>
+<% elsif params[:display_name] %>
+ <div class="inner22"><%= t(params[:max_id] ? 'changeset.list.no_more_user' : 'changeset.list.empty_user') %></div>
<% else %>
- <h4><%= t('changeset.list.empty_anon_html') %></h4>
+ <div class="inner22"><%= t(params[:max_id] ? 'changeset.list.no_more' : 'changeset.list.empty') %></div>
<% 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
<% end -%>
</table>
-<ul class='secondary-actions clearfix'>
- <li><%= link_to t('diary_entry.comments.older_comments') , { :page => @comment_pages.current.next} if @comment_pages.current.next %></li>
- <li><%= link_to t('diary_entry.comments.newer_comments'), { :page => @comment_pages.current.previous } if @comment_pages.current.previous %></li>
-</ul>
+<div class='secondary-actions clearfix'>
+ <span><%= 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 %></span>
+</div>
<% if @this_user %>
<%= user_image @this_user %>
<% end %>
- <h2><%= h(@title) %></h2>
+ <h1><%= h(@title) %></h1>
<ul class='secondary-actions clearfix'>
<% unless params[:friends] or params[:nearby] -%>
+++ /dev/null
-<%= form_tag :controller => "export", :action => "finish" do %>
- <%= hidden_field_tag 'format', 'osm' %>
-
- <div class="export_bounds inner12">
- <div class='export_area_inputs'>
- <%= text_field_tag('maxlat', nil, :size => 10, :class => "export_bound") %>
- <br/>
- <%= text_field_tag('minlon', nil, :size => 10, :class => "export_bound") %>
- <%= text_field_tag('maxlon', nil, :size => 10, :class => "export_bound") %>
- <br/>
- <%= text_field_tag('minlat', nil, :size => 10, :class => "export_bound") %>
- </div>
- <a id="drag_box" class='export_hint button' href="#"><%= t'export.start.manually_select' %></a>
- </div>
-
- <div id="export_osm">
- <h4><%= t'export.start.licence' %></h4>
-
- <div class="export_details inner12">
- <p><%= raw t'export.start.export_details' %></p>
- </div>
-
- <div id="export_osm_too_large">
- <h4><%= t'export.start.too_large.heading' %></h4>
-
- <div class="export_details inner12">
- <p><%= t'export.start.too_large.body' %></p>
- <dl>
- <dt><a href="http://planet.openstreetmap.org/"><%= t'export.start.too_large.planet.title' %></a></dt>
- <dd><%= t'export.start.too_large.planet.description' %></dd>
-
- <dt><a href="http://download.geofabrik.de/"><%= t'export.start.too_large.geofabrik.title' %></a></dt>
- <dd><%= t'export.start.too_large.geofabrik.description' %></dd>
-
- <dt><a href="http://metro.teczno.com/"><%= t'export.start.too_large.metro.title' %></a></dt>
- <dd><%= t'export.start.too_large.metro.description' %></dd>
-
- <dt><a href="http://wiki.openstreetmap.org/wiki/Download"><%= t'export.start.too_large.other.title' %></a></dt>
- <dd><%= t'export.start.too_large.other.description' %></dd>
- </dl>
- </div>
- </div>
- </div>
-
- <div class="inner12">
- <%= submit_tag t('export.start.export_button'), :id => "export_commit" %>
- </div>
-<% end %>
<p class="search_results_entry inner12"><%= t 'geocoder.results.no_results' %></p>
<% else %>
<ul class='results-list'>
- <% @results.each do |result| %>
- <li><p class="inner12 search_results_entry clearfix"><%= result_to_html(result) %></p></li>
- <% end %>
-</ul>
+ <% @results.each do |result| %>
+ <li><p class="inner12 search_results_entry clearfix"><%= result_to_html(result) %></p></li>
+ <% end %>
+ </ul>
<% if @more_params %>
<div class="search_more">
- <div class="inner12 search_results_entry">
- <%= link_to t('geocoder.results.more_results'), url_for(@more_params), :class => "button" %>
- </div>
- <%= 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;" %>
</div>
<% end %>
<% end %>
+<h2>
+ <a class="geolink" href="<%= root_path %>"><span class="icon close"></span></a>
+ <%= t('site.sidebar.search_results') %>
+</h2>
<% @sources.each do |source| %>
- <h4><%= raw(t "geocoder.search.title.#{source}") %></h4>
- <div class="search_results_entry" id="<%= "search_#{source}" %>">
- <%= image_tag "searching.gif", :class => "search_searching" %>
+ <h4 class="inner12"><%= raw(t "geocoder.search.title.#{source}") %></h4>
+ <div class="search_results_entry" data-href="<%= url_for params.merge(:action => "search_#{source}") %>">
+ <%= image_tag "searching.gif", :class => "loader" %>
</div>
- <script type="text/javascript">
- $("#search_<%= source %>").load("<%= raw url_for params.merge(:action => "search_#{source}") %>");
- </script>
<% end %>
--- /dev/null
+<div id="content" class="<%= content_for :content_class %>">
+ <% if content_for? :content %>
+ <%= yield :content %>
+ <% else %>
+ <%= render :partial => "layouts/flash", :locals => { :flash => flash } %>
+ <% if content_for? :heading %>
+ <div class="content-heading">
+ <div class="content-inner">
+ <%= yield :heading %>
+ </div>
+ </div>
+ <% end %>
+ <div class="content-body">
+ <div class="content-inner">
+ <%= yield %>
+ </div>
+ </div>
+ <% end %>
+</div>
+++ /dev/null
-<div class="dropdown edit_menu">
- <%= link_to link_text, edit_path,
- :id => 'editanchor',
- :data => { :editor => preferred_editor },
- :class => "geolink tab #{link_class}" %>
- <a class='dropdown-toggle' data-toggle='dropdown' href='#'>
- <b class="caret"></b>
- </a>
- <ul class='dropdown-menu'>
- <% Editors::RECOMMENDED_EDITORS.each do |editor| %>
- <li>
- <%= link_to t('layouts.edit_with', :editor => t("editor.#{editor}.description")),
- edit_path(:editor => editor),
- :data => { :editor => editor },
- :class => "geolink #{link_class}" %>
- </li>
- <% end %>
- </ul>
-</div>
<% if flash[:error] %>
- <div id="error" class="flash"><%=image_tag("notice.png", :class => "small_icon", :border=>0)%><%= raw flash[:error] %></div>
+ <p class="error">
+ <%= image_tag("notice.png", :class => "small_icon", :border => 0) %>
+ <%= raw flash[:error] %>
+ </p>
<% end %>
<% if flash[:warning] %>
- <div id="warning" class="flash"><%=image_tag("notice.png", :class => "small_icon", :border=>0)%><%= raw flash[:warning] %></div>
+ <p class="warning">
+ <%= image_tag("notice.png", :class => "small_icon", :border => 0) %>
+ <%= raw flash[:warning] %>
+ </p>
<% end %>
<% if flash[:notice] %>
- <div id="notice" class="flash"><%=image_tag("notice.png", :class => "small_icon", :border=>0)%><%= raw flash[:notice] %></div>
+ <p class="notice">
+ <%= image_tag("notice.png", :class => "small_icon", :border => 0) %>
+ <%= raw flash[:notice] %>
+ </p>
<% end %>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0"/>
+ <!--[if lt IE 9]><%= javascript_include_tag "html5shiv" %><![endif]-->
<%= 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 IE]>
<% end -%>
<%= style_rules %>
<%= yield :head %>
+ <%= yield :auto_discovery_link_tag %>
<%= csrf_meta_tag %>
<script type="text/javascript">
I18n.defaultLocale = "<%= I18n.default_locale %>";
OSM.oauth_consumer_secret = "<%= @oauth.client_application.secret %>";
<% end -%>
</script>
- <title><%= t 'layouts.project_name.title' %><%= ' | '+ @title if @title %></title>
+ <title><%= t 'layouts.project_name.title' %><%= ' | ' + @title if @title %></title>
</head>
--- /dev/null
+<header class="closed">
+ <h1>
+ <a href="<%= root_path %>" class="geolink">
+ <%= image_tag "osm_logo.png", :alt => t('layouts.logo.alt_text'), :class => 'logo' %>
+ <%= t 'layouts.project_name.h1' %>
+ </a>
+ </h1>
+ <a href="#" id="menu-icon"></a>
+ <nav class='primary'>
+ <%= content_for :header %>
+ <ul>
+ <li id="edit_tab" class="dropdown <%= current_page_class(edit_path) %>">
+ <%= link_to t('layouts.edit'), edit_path, :class => "tab geolink editlink",
+ :id => 'editanchor',
+ :data => { :editor => preferred_editor }
+ %><a class='dropdown-toggle' data-toggle='dropdown' href='#'><b class="caret"></b></a>
+ <ul class='dropdown-menu'>
+ <% Editors::RECOMMENDED_EDITORS.each do |editor| %>
+ <li>
+ <%= link_to t('layouts.edit_with', :editor => t("editor.#{editor}.description")),
+ edit_path(:editor => editor),
+ :data => { :editor => editor },
+ :class => "geolink editlink" %>
+ </li>
+ <% end %>
+ </ul>
+ </li>
+ <li id="history_tab" class="<%= current_page_class(history_path) %>">
+ <%= link_to t('layouts.history'), history_path, :class => 'tab geolink' %>
+ </li>
+ <li id="export_tab" class="<%= current_page_class(export_path) %>">
+ <%= link_to t('layouts.export'), export_path, :class => 'tab geolink' %>
+ </li>
+ </ul>
+ </nav>
+ <nav class='secondary'>
+ <ul>
+ <li class="compact-hide <%= current_page_class(traces_path) %>"><%= link_to t('layouts.gps_traces'), traces_path %></li>
+ <li class="compact-hide <%= current_page_class(diary_path) %>"><%= link_to t('layouts.user_diaries'), diary_path %></li>
+ <li class="compact-hide <%= current_page_class(help_path) %>"><%= link_to t('layouts.help'), help_path %></li>
+ <li class="compact-hide <%= current_page_class(about_path) %>"><%= link_to t('layouts.about'), about_path %></li>
+ <li id="compact-secondary-nav" class="dropdown">
+ <a class="dropdown-toggle" data-toggle="dropdown" href="#">More <b class="caret"></b></a>
+ <ul class="dropdown-menu">
+ <li class="<%= current_page_class(traces_path) %>"><%= link_to t('layouts.gps_traces'), traces_path %></li>
+ <li class="<%= current_page_class(diary_path) %>"><%= link_to t('layouts.user_diaries'), diary_path %></li>
+ <li class="<%= current_page_class(help_path) %>"><%= link_to t('layouts.help'), help_path %></li>
+ <li class="<%= current_page_class(about_path) %>"><%= link_to t('layouts.about'), about_path %></li>
+ </ul>
+ </li>
+ </ul>
+ <% if @user && @user.id %>
+ <div class='dropdown user-menu logged-in'>
+ <a class='dropdown-toggle' data-toggle='dropdown' href="#">
+ <%= user_thumbnail_tiny(@user, :size => 25, :width => 25, :height => 25)
+ %><%= render :partial => 'layouts/inbox'
+ %><span class="user-button"><span class='username'><%= @user.display_name %></span>
+ <b class="caret"></b></span>
+ </a>
+ <ul class='dropdown-menu'>
+ <li>
+ <%= link_to inbox_path(:display_name => @user.display_name) do %>
+ <span class='count-number'><%= number_with_delimiter(@user.new_messages.size) %></span>
+ <%= t('message.inbox.my_inbox') %>
+ <% end %>
+ </li>
+ <li>
+ <%= link_to t('user.view.my profile'), user_path(:display_name => @user.display_name) %>
+ </li>
+ <li>
+ <%= link_to t('user.view.my settings'), :controller => 'user', :action => 'account', :display_name => @user.display_name %>
+ </li>
+ <li class="divider"></li>
+ <li>
+ <%= yield :greeting %>
+ </li>
+ <li>
+ <%= link_to t('layouts.logout'), logout_path(:session => request.session_options[:id], :referer => request.fullpath) %>
+ </li>
+ </ul>
+ </div>
+ <% else %>
+ <ul class="user-menu clearfix">
+ <li><%= link_to t('layouts.log_in'), login_path(:referer => request.fullpath) %></li>
+ <li><%= link_to t('layouts.sign_up'), user_new_path %></li>
+ </ul>
+ <% end %>
+ </nav>
+</header>
-<span id="inboxanchor" class="count-number">
- <%= user_thumbnail_tiny(@user, :size => 20, :width => 20, :height => 20) %><span><%= @user.new_messages.size %></span>
-</span>
\ No newline at end of file
+<% if @user.new_messages.size > 0 %>
+<span id="inboxanchor" class="count-number"><%= @user.new_messages.size %></span>
+<% end %>
--- /dev/null
+<%= form_tag search_path, :class => "search_form" do %>
+ <%= submit_tag t('site.search.submit_text') %>
+ <div class='query_wrapper'>
+ <input type="text" name="query" value="<%= params[:query] %>" placeholder="<%= t('site.search.search') %>">
+ <%= link_to t('site.search.where_am_i'), '#', { :class => "describe_location", :title => t('site.search.where_am_i_title') } %>
+ </div>
+<% end %>
+++ /dev/null
-<div class='dropdown' id='greeting'>
- <a class='dropdown-toggle' data-toggle='dropdown' href="#">
- <%= render :partial => 'layouts/inbox' %>
- <%= @user.display_name %>
- <b class="caret"></b>
- </a>
- <ul class='dropdown-menu'>
- <li>
- <%= link_to inbox_path(:display_name => @user.display_name) do %>
- <span class='count-number'><%= number_with_delimiter(@user.new_messages.size) %></span>
- <%= t('message.inbox.my_inbox') %>
- <% end %>
- </li>
- <li>
- <%= link_to t('user.view.my profile'), user_path(:display_name => @user.display_name) %>
- </li>
- <li>
- <%= link_to t('user.view.my settings'), :controller => 'user', :action => 'account', :display_name => @user.display_name %>
- </li>
- <li class="divider"></li>
- <li>
- <%= yield :greeting %>
- </li>
- <li>
- <%= link_to t('layouts.logout'), logout_path(:session => request.session_options[:id], :referer => request.fullpath) %>
- </li>
- </ul>
-</div>
--- /dev/null
+<% content_for :head do %>
+ <%= javascript_include_tag "index" %>
+<% end %>
+
+<% content_for(:body_class) { "map-layout" } %>
+
+<% if @user and !@user.home_lon.nil? and !@user.home_lat.nil? %>
+ <% content_for :greeting do %>
+ <%= link_to t("layouts.home"),
+ "#",
+ :id => "homeanchor",
+ :class => "set_position",
+ :data => { :lat => @user.home_lat,
+ :lon => @user.home_lon,
+ :zoom => 15 } %>
+ <% end %>
+<% end %>
+
+<% content_for :header do %>
+ <%= render :partial => "layouts/search" %>
+<% end %>
+
+<% content_for :content do %>
+ <div id="sidebar">
+ <%= render :partial => "layouts/search" %>
+
+ <% if STATUS == :database_offline or STATUS == :api_offline %>
+ <p class="error"><%= t 'layouts.osm_offline' %></p>
+ <% elsif STATUS == :database_readonly or STATUS == :api_readonly %>
+ <p class="error"><%= t 'layouts.osm_read_only' %></p>
+ <% end %>
+
+ <div id="flash">
+ <%= render :partial => "layouts/flash" %>
+ </div>
+
+ <div id="browse_status"></div>
+
+ <div id="sidebar_loader" style="display: none;">
+ <img alt="<%= t('browse.start_rjs.loading') %>" class="loader" src="<%= image_path("searching.gif") %>">
+ </div>
+
+ <div id="sidebar_content">
+ <%= yield %>
+ </div>
+
+ <% unless @user %>
+ <div class="welcome">
+ <h2><%= t 'layouts.intro_header' %></h2>
+ <p><%= t 'layouts.intro_text' %></p>
+ <a class="button learn-more" href="<%= about_path %>"><%= t('layouts.learn_more') %></a>
+ <a class="button sign-up" href="<%= user_new_path %>"><%= t('layouts.start_mapping') %></a>
+ </div>
+ <% end %>
+ </div>
+
+ <noscript>
+ <div id="noscript">
+ <p><%= t 'site.index.js_1' %></p>
+ <p><%= t 'site.index.js_2' %></p>
+ </div>
+ </noscript>
+
+ <div id="map-ui">
+ </div>
+
+ <div id="map" tabindex="2">
+ </div>
+
+ <div id="attribution">
+ <table width="100%">
+ <tr>
+ <td class="attribution_license"><%= t 'site.index.license.license_url' %></td>
+ <td class="attribution_project"><%= t 'site.index.license.project_url' %></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="attribution_notice"><%= t 'site.index.license.copyright' %></td>
+ </tr>
+ </table>
+ </div>
+<% end %>
+
+<%= render :template => 'layouts/site' %>
<!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<%= I18n.locale %>" lang="<%= I18n.locale %>" dir="<%= dir %>">
+<html lang="<%= I18n.locale %>" dir="<%= dir %>">
<%= render :partial => "layouts/head" %>
<body class="<%= body_class %>">
- <h1 id="small-title">
- <%= image_tag "osm_logo.png", :size => "16x16", :alt => t('layouts.logo.alt_text') %>
- <%= t 'layouts.project_name.h1' %>
- </h1>
- <div id="left">
- <div id="logo">
- <%= link_to(image_tag("osm_logo.png",
- :size => "120x120",
- :alt => t('layouts.logo.alt_text')),
- root_path) %>
- <h1><%= t 'layouts.project_name.h1' %></h1>
- <h2><%= t('layouts.tag_line') %></h2>
- </div>
- <%= yield :optionals %>
- <% unless @user %>
- <div class="sidebar-copy intro">
- <p><%= t 'layouts.intro_1' %></p>
- <p>
- <%= t 'layouts.intro_2_html',
- :download => link_to(t('layouts.intro_2_download'), "http://planet.openstreetmap.org/"),
- :use => link_to(t('layouts.intro_2_use'), t('layouts.intro_2_use_url')),
- :license => link_to(t('layouts.intro_2_license'), copyright_path),
- :create_account => link_to(t('layouts.intro_2_create_account'), user_new_path)
- %>
- </p>
- </div>
- <% end %>
- <% if STATUS == :database_offline or STATUS == :api_offline %>
- <div class="sidebar-alert">
- <p><%= t 'layouts.osm_offline' %></p>
- </div>
- <% elsif STATUS == :database_readonly or STATUS == :api_readonly %>
- <div class="sidebar-alert">
- <p><%= t 'layouts.osm_read_only' %></p>
- </div>
- <% end %>
- <ul id="left_menu" class="left_menu">
- <li>
- <h4><%= t'layouts.help' %></h4>
- <ul>
- <li><%= link_to(t('layouts.help_centre'), t('layouts.help_url'), :title => t('layouts.help_title')) %></li>
- <li><%= link_to(t('layouts.documentation'), t('layouts.wiki_url'), :title => t('layouts.documentation_title')) %></li>
- </ul>
- </li>
- <li>
- <h4><%= t'layouts.community' %></h4>
- <ul>
- <li><a href="http://blogs.openstreetmap.org/" title="<%= t 'layouts.community_blogs_title' %>"><%= t 'layouts.community_blogs' %></a></li>
- <li><a href="http://www.osmfoundation.org" title="<%= t 'layouts.foundation_title' %>"><%= t 'layouts.foundation' %></a></li>
- <li><%= link_to(t('layouts.user_diaries'), diary_path, {
- :title => t('layouts.user_diaries_tooltip')
- }) %></li>
- </ul>
- </li>
- <li>
- <h4><%= t'layouts.data' %></h4>
- <ul>
- <li><%= link_to t('layouts.copyright'), copyright_path %></li>
- </ul>
- <ul>
- <li><%= link_to t('layouts.export_data'), export_path %></li>
- </ul>
- <ul>
- <li><%= link_to t('layouts.gps_traces'), traces_path %></li>
- </ul>
- </li>
- <%= yield :left_menu %>
- </ul>
- <a title="<%= h(t('layouts.make_a_donation.title')) %>" href="http://donate.openstreetmap.org/" class="donate">
- <span class='icon donate'></span>
- <span><%= h(t('layouts.make_a_donation.text')) %></span>
- </a>
- <div class='sidebar-copy'>
- <p class='deemphasize'><%= t 'layouts.partners_html',
- :ucl => link_to(t('layouts.partners_ucl'), "http://www.vr.ucl.ac.uk"),
- :ic => link_to(t('layouts.partners_ic'), "http://www.imperial.ac.uk/"),
- :bytemark => link_to(t('layouts.partners_bytemark'), "http://www.bytemark.co.uk"),
- :partners => link_to(t('layouts.partners_partners'), t('layouts.partners_url')) %>
- </p>
- </div>
- </div>
- <div id='top-bar'>
- <% if @user and @user.id %>
- <%= render :partial => "layouts/user_menu" %>
- <% else %>
- <ul class='secondary-actions' id='greeting'>
- <li><%= link_to t('layouts.log_in'), login_path(:referer => request.fullpath), {:id => 'loginanchor', :title => t('layouts.log_in_tooltip')} %></li>
- <li><%= link_to t('layouts.sign_up'), user_new_path, {:id => 'registeranchor', :title => t('layouts.sign_up_tooltip')} %></li>
- </ul>
- <% end %>
- <ul id="tabnav">
- <li id="view_tab">
- <%= link_to t('layouts.view'), root_path, :class => 'tab geolink llz layers' %>
- </li><li id="edit_tab">
- <%= render :partial => 'layouts/edit_menu',
- :locals => { :link_text => t('layouts.edit'), :link_class => 'llz object' }%>
- </li><li id="history_tab">
- <%= link_to t('layouts.history'), browse_changesets_path, :class => 'tab geolink bbox' %>
- </li>
- </ul>
- </div>
- <div class="wrapper">
- <%= render :partial => "layouts/flash", :locals => { :flash => flash } %>
- <% if content_for? :heading %>
- <div class="content-heading">
- <%= yield :heading %>
- </div>
- <% end %>
- <div id="content" class="clearfix">
- <%= yield %>
- </div>
- </div>
+ <%= render :partial => "layouts/header" %>
+ <%= render :partial => "layouts/content" %>
<% if defined?(PIWIK) -%>
<noscript><p><img src="<%= request.protocol %><%= PIWIK['location'] %>/piwik.php?idsite=<%= PIWIK['site'] %>" style="border:0" alt="" /></p></noscript>
<% end -%>
--- /dev/null
+<%= content_for :auto_discovery_link_tag %>
+<%= yield %>
+++ /dev/null
-<% if @user and !@user.home_lon.nil? and !@user.home_lat.nil? %>
- <% content_for :greeting do %>
- <%= link_to t("layouts.home"),
- "#",
- :id => "homeanchor",
- :class => "set_position",
- :data => { :lat => @user.home_lat,
- :lon => @user.home_lon,
- :zoom => 15 } %>
- <% end %>
-<% end %>
var params = {};
var mapParams = OSM.mapParams();
- if (mapParams.object) {
+ if (mapParams.object &&
+ mapParams.object.type !== 'note' &&
+ mapParams.object.type !== 'changeset') {
params.id = mapParams.object.type[0] + mapParams.object.id;
} else {
<% if @lat && @lon -%>
});
});
- var mapMoved = $.throttle(250, function(lon, lat, zoom, minlon, minlat, maxlon, maxlat) {
- updatelinks({ lon: lon, lat: lat }, zoom, null, [[minlat, minlon], [maxlat, maxlon]]);
+ var mapMoved = $.throttle(250, function(lon, lat, zoom) {
+ updatelinks({ lon: lon, lat: lat }, zoom);
var hash = OSM.formatHash({ lon: lon, lat: lat, zoom: zoom });
if (hash !== location.hash) {
+++ /dev/null
-<% content_for :optionals do %>
- <div class="optionalbox">
- <div class="search_container">
- <div id="search_field">
- <%= form_tag url_for(:controller => :geocoder, :action => :search), :id => "search_form" do %>
- <%= submit_tag t('site.search.submit_text') %>
- <%= text_field_tag :query, h(params[:query]), :tabindex => "1", :placeholder => t('site.search.search'), :autofocus => "autofocus" %>
- <% end %>
- </div>
- </div>
- <p class='search_help deemphasize'>
- <%= raw(t 'site.search.search_help') %>
- <%= link_to t('site.search.where_am_i'), { :controller => :geocoder, :action => :search }, { :id => "describe_location", :title => t('site.search.where_am_i_title') } %>
- </p>
- </div>
-<% end %>
+++ /dev/null
-<div id="sidebar">
- <div class="sidebar_heading">
- <h4 id="sidebar_title"><% t 'site.sidebar.search_results' %></h4>
- <a class="sidebar_close" href="#"><%= t 'site.sidebar.close' %></a>
- </div>
- <div id="sidebar_content">
- <%= render :template => 'export/start' if params[:export] %>
- </div>
-</div>
--- /dev/null
+<div class='attr'>
+ <div class='byosm'>
+ <%= t "about_page.copyright_html" %>
+ </div>
+
+ <div class='user-image'></div>
+
+ <h1><%= raw t "about_page.used_by", :name => "<span class='user-name'>OpenStreetMap</span>" %></h1>
+</div>
+
+<div class='text'>
+ <div class='section'>
+ <p><strong><%= t "about_page.lede_text" %></strong></p>
+ <h2><div class='icon local'></div><%= t "about_page.local_knowledge_title" %></h2>
+ <p><%= t "about_page.local_knowledge_html" %></p>
+ </div>
+
+ <div class='section'>
+ <h2><div class='icon community'></div><%= t "about_page.community_driven_title" %></h2>
+ <p><%= t "about_page.community_driven_html", :diary_path => diary_path %></p>
+ </div>
+
+ <div class='section' id='open-data'>
+ <h2><div class='icon open'></div><%= t "about_page.open_data_title" %></h2>
+ <p><%= t "about_page.open_data_html", :copyright_path => copyright_path %></p>
+ </div>
+
+ <div class='section' id='partners'>
+ <h2><div class='icon partners'></div><%= t "about_page.partners_title" %></h2>
+ <p><%= t 'layouts.partners_html',
+ :ucl => link_to(t('layouts.partners_ucl'), "http://www.vr.ucl.ac.uk"),
+ :ic => link_to(t('layouts.partners_ic'), "http://www.imperial.ac.uk/"),
+ :bytemark => link_to(t('layouts.partners_bytemark'), "http://www.bytemark.co.uk"),
+ :partners => link_to(t('layouts.partners_partners'), t('layouts.partners_url')) %>
+ </p>
+ </div>
+</div>
<!-- Maybe ease foreigners back to their native page -->
<% if t('license_page.legal_babble', :locale => I18n.locale) != t('license_page.legal_babble', :locale => :en) %>
- <h2><%= t 'license_page.native.title' %></h2>
+ <h1><%= t 'license_page.native.title' %></h1>
<p>
<%= raw t 'license_page.native.text',
:native_link => link_to(t('license_page.native.native_link'),
<% else %>
<!-- Maybe note that this page has been translated -->
<% if t('license_page.legal_babble', :locale => @locale) != t('license_page.legal_babble', :locale => :en) %>
- <h2><%= t 'license_page.foreign.title' %></h2>
+ <h1><%= t 'license_page.foreign.title' %></h1>
<p>
<%= raw t 'license_page.foreign.text',
:english_original_link => link_to(t('license_page.foreign.english_link'),
<% end %>
<% end %>
- <h2><%= t "license_page.legal_babble.title_html", :locale => @locale %></h2>
+ <h1><%= t "license_page.legal_babble.title_html", :locale => @locale %></h1>
<% end %>
-<% if STATUS == :database_offline or STATUS == :api_offline %>
-<p><%= t 'layouts.osm_offline' %>
-</p>
-<% elsif STATUS == :database_readonly or STATUS == :api_readonly %>
-<p><%= t 'layouts.osm_read_only' %>
-</p>
-<% elsif !@user.data_public? %>
-<p><%= t 'site.edit.not_public' %></p>
-<p><%= 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'}) %></p>
-<p><%= raw t 'site.edit.anon_edits', :link => link_to(t('site.edit.anon_edits_link_text'), t('site.edit.anon_edits_link')) %></p>
-<% 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 %>
+ <p><%= t 'layouts.osm_offline' %></p>
+ <% elsif STATUS == :database_readonly or STATUS == :api_readonly %>
+ <p><%= t 'layouts.osm_read_only' %></p>
+ <% elsif !@user.data_public? %>
+ <p><%= t 'site.edit.not_public' %></p>
+ <p><%= 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'}) %></p>
+ <p><%= raw t 'site.edit.anon_edits', :link => link_to(t('site.edit.anon_edits_link_text'), t('site.edit.anon_edits_link')) %></p>
+ <% else %>
+ <%= render :partial => preferred_editor %>
+ <% end %>
<% end %>
--- /dev/null
+<% set_title(t('export.title')) %>
+
+<h2>
+ <a class="geolink" href="<%= root_path %>"><span class="icon close"></span></a>
+ <%= t 'export.title' %>
+</h2>
+
+<%= form_tag({:controller => "export", :action => "finish"}, :class => "export_form") do %>
+ <%= hidden_field_tag 'format', 'osm' %>
+
+ <div class='export_area_inputs'>
+ <div class='export_boxy' style="border: 1px solid #ccc;">
+ <%= text_field_tag('maxlat', nil, :size => 10, :class => "export_bound") %>
+ <br/>
+ <%= text_field_tag('minlon', nil, :size => 10, :class => "export_bound") %>
+ <%= text_field_tag('maxlon', nil, :size => 10, :class => "export_bound") %>
+ <br/><br/>
+ <%= text_field_tag('minlat', nil, :size => 10, :class => "export_bound") %>
+ </div>
+ <a id='drag_box' href="#"><%= t'export.start.manually_select' %></a>
+ </div>
+
+ <h4><%= t'export.start.licence' %></h4>
+ <p><%= raw t 'export.start.export_details' %></p>
+
+ <div id="export_osm_too_large">
+ <p class="warning">
+ <%= t'export.start.too_large.body' %>
+ </p>
+ <dl class="inner12">
+ <dt><a href="http://planet.openstreetmap.org/"><%= t'export.start.too_large.planet.title' %></a></dt>
+ <dd><%= t'export.start.too_large.planet.description' %></dd>
+
+ <dt><a href="http://download.geofabrik.de/"><%= t'export.start.too_large.geofabrik.title' %></a></dt>
+ <dd><%= t'export.start.too_large.geofabrik.description' %></dd>
+
+ <dt><a href="http://metro.teczno.com/"><%= t'export.start.too_large.metro.title' %></a></dt>
+ <dd><%= t'export.start.too_large.metro.description' %></dd>
+
+ <dt><a href="http://wiki.openstreetmap.org/wiki/Download"><%= t'export.start.too_large.other.title' %></a></dt>
+ <dd><%= t'export.start.too_large.other.description' %></dd>
+ </dl>
+ </div>
+
+ <div class="export_button">
+ <%= submit_tag t('export.start.export_button'), :id => "export_commit" %>
+ </div>
+<% end %>
--- /dev/null
+<% content_for :heading do %>
+ <h1><%= t "help_page.title" %></h1>
+<% end %>
+
+<p class='introduction'><%= t "help_page.introduction" %></p>
+
+<% ['welcome', 'help', 'wiki'].each do |site| %>
+ <% unless site == 'welcome' && !@user %>
+ <div class='<%= site %> help-item'>
+ <h3>
+ <a href='<%= t "help_page.#{site}.url" %>'>
+ <%= t "help_page.#{site}.title" %>
+ </a>
+ </h3>
+ <p><%= t "help_page.#{site}.description" %></p>
+ </div>
+ <% end %>
+<% end %>
});
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));
}
-<% content_for :head do %>
- <%= javascript_include_tag "index" %>
-<% end %>
-
-<%= render :partial => 'home_link' %>
-<%= render :partial => 'sidebar' %>
-<%= render :partial => 'search' %>
-
-<noscript>
- <div id="noscript">
- <p><%= t 'site.index.js_1' %></p>
- <p><%= t 'site.index.js_2' %></p>
- </div>
-</noscript>
-
-<div id="map-ui">
-</div>
-
-<div id="map" tabindex="2">
-</div>
-
-<div id="attribution">
- <table width="100%">
- <tr>
- <td class="attribution_license"><%= t'site.index.license.license_url' %></td>
- <td class="attribution_project"><%= t'site.index.license.project_url' %></td>
- </tr>
- <tr>
- <td colspan="2" class="attribution_notice"><%= t'site.index.license.copyright' %></td>
- </tr>
- </table>
-</div>
-
+<%
+ set_title()
+ content_for(:content_class) { "overlay-sidebar" }
+%>
<% end %>
<% content_for :heading do %>
- <h2><%= t "welcome_page.title" %></h2>
+ <h1><%= t "welcome_page.title" %></h1>
<% end %>
<p><%= t "welcome_page.introduction_html" %></p>
<div class='col12 clearfix icon-list'>
<h3><%= t "welcome_page.questions.title" %></h3>
<span class='sprite small term question'></span>
- <p><%= t "welcome_page.questions.paragraph_1_html" %></p>
+ <p><%= t "welcome_page.questions.paragraph_1_html", :help_url => help_path %></p>
</div>
<div class='clearfix center'>
<p><%= t "welcome_page.add_a_note.paragraph_1_html" %></p>
<p><%= t "welcome_page.add_a_note.paragraph_2_html", :map_url => root_path %></p>
</div>
-</div>
\ No newline at end of file
+</div>
<% 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')})
<% content_for :heading do %>
- <h2><%= t 'user.account.my settings' %></h2>
+ <h1><%= t 'user.account.my settings' %></h1>
<ul class='secondary-actions clearfix'>
<li><%= link_to t('user.account.return to profile'), :controller => 'user', :action => 'view', :display_name => @user.display_name %></li>
<li><%= link_to t('user.view.oauth settings'), :controller => 'oauth_clients', :action => 'index' %></li>
<% content_for :heading do %>
- <h2><%= t 'user.confirm.heading' %></h2>
+ <h1><%= t 'user.confirm.heading' %></h1>
<div class='header-illustration confirm-main'></div>
<% end %>
<% content_for :heading do %>
- <h2><%= t 'user.no_such_user.heading', :user => h(@not_found_user) %></h2>
+ <h1><%= t 'user.no_such_user.heading', :user => h(@not_found_user) %></h1>
<% end %>
<p><%= t 'user.no_such_user.body', :user => h(@not_found_user) %></p>
<div id='userinformation'>
<%= user_image @this_user %>
<div class='userinformation-inner'>
- <h2><%= @this_user.display_name %><%= role_icons(@this_user) %></h2>
+ <h1><%= @this_user.display_name %><%= role_icons(@this_user) %></h1>
<% if @user and @this_user.id == @user.id %>
- <!-- Displaying user's own profile page -->
+ <!-- Displaying user's own profile page to themself -->
<ul class='secondary-actions clearfix'>
<li>
<%= link_to t('user.view.my edits'), :controller => 'changeset', :action => 'list', :display_name => @user.display_name %>
</ul>
<% else %>
-
+ <!-- Displaying user profile page to the public -->
<ul class='secondary-actions clearfix'>
<li>
# 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 )
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
hide_areas: Схаваць вобласьці
history_for_feature: Гісторыя %{feature}
load_data: Загрузіць зьвесткі
- loaded_an_area_with_num_features: Вы загрузілі мясцовасьць, якая ўтрымлівае %{num_features} аб’ектаў. Увогуле, некаторыя браўзэры ня змогуць апрацаваць такую колькасьць зьвестак. Звычайна найлепшы вынік назіраецца, калі аб’ектаў менш за %{max_features}, пры выкананьні яшчэ нейкіх задачаў браўзэр можа страціць хуткасьць/завіснуць. Калі Вы ўпэўненыя, што жадаеце паказаць гэтыя зьвесткі, націсьніце кнопку ніжэй.
loading: Загрузка…
manually_select: Выбраць іншы абшар
notes_layer_name: Прагляд нататак
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:
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
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
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
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: Περιήγηση Σημειώσεων
name: "Remote Control"
description: "Remote Control (JOSM or Merkaartor)"
browse:
+ created: "Created"
+ closed: "Closed"
+ created_html: "Created <abbr title='%{title}'>%{time} ago</abbr>"
+ closed_html: "Closed <abbr title='%{title}'>%{time} ago</abbr>"
+ created_by_html: "Created <abbr title='%{title}'>%{time} ago</abbr> by %{user}"
+ deleted_by_html: "Deleted <abbr title='%{title}'>%{time} ago</abbr> by %{user}"
+ edited_by_html: "Edited <abbr title='%{title}'>%{time} ago</abbr> by %{user}"
+ closed_by_html: "Closed <abbr title='%{title}'>%{time} ago</abbr> 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
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."
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} <abbr title='%{exact_time}'>%{when} ago</abbr>"
+ open_by_anonymous: "Created by anonymous <abbr title='%{exact_time}'>%{when} ago</abbr>"
+ commented_by: "Comment from %{user} <abbr title='%{exact_time}'>%{when} ago</abbr>"
+ commented_by_anonymous: "Comment from anonymous <abbr title='%{exact_time}'>%{when} ago</abbr>"
+ closed_by: "Resolved by %{user} <abbr title='%{exact_time}'>%{when} ago</abbr>"
+ closed_by_anonymous: "Resolved by anonymous <abbr title='%{exact_time}'>%{when} ago</abbr>"
+ reopened_by: "Reactivated by %{user} <abbr title='%{exact_time}'>%{when} ago</abbr>"
+ reopened_by_anonymous: "Reactivated by anonymous <abbr title='%{exact_time}'>%{when} ago</abbr>"
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"
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 <a href='http://wiki.openstreetmap.org/wiki/Beginners_Guide_1.3'>Beginners Guide</a>."
- 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:
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"
licence: "Licence"
export_details: 'OpenStreetMap data is licensed under the <a href="http://opendatacommons.org/licenses/odbl/1.0/">Open Data Commons Open Database License</a> (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"
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:
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
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"
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"
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
questions:
title: Any questions?
paragraph_1_html: |
- Need help mapping, or not clear on how to use OpenStreetMap? Get your questions answered
- on <a href='http://help.openstreetmap.org/'>the help website</a>.
+ OpenStreetMap has several resources for learning about the project, asking and answering
+ questions, and collaboratively discussing and documenting mapping topics.
+ <a href='%{help_url}'>Get help here</a>.
start_mapping: Start Mapping
add_a_note:
title: No Time To Edit? Add a Note!
Just go to <a href='%{map_url}'>the map</a> and click the note icon:
<span class='icon note'></span>. 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: <span>©</span>OpenStreetMap<br>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 <a href='%{diary_path}'>user diaries</a>,
+ <a href='http://blogs.openstreetmap.org/'>community blogs</a>, and
+ the <a href='http://www.osmfoundation.org/'>OSM Foundation</a> website.
+ open_data_title: Open Data
+ open_data_html: |
+ OpenStreetMap is <i>open data</i>: 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 <a href='%{copyright_path}'>Copyright and
+ License page</a> for details.
+ partners_title: Partners
notifier:
diary_comment_notification:
subject: "[OpenStreetMap] %{user} commented on your diary entry"
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' <a href='http://wiki.openstreetmap.org/wiki/Search'>more examples...</a>"
key:
table:
entry:
overlays: Enable overlays for troubleshooting the map
title: "Layers"
copyright: "© <a href='%{copyright_url}'>OpenStreetMap contributors</a>"
+ donate_link_text: "<a class='donate-attr' href='%{donate_url}'>Make a Donation</a>"
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."
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
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
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
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
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
hide_areas: להסתרת אזורים
history_for_feature: ההיסטוריה של %{feature}
load_data: טעינת נתונים
- loaded_an_area_with_num_features: "האזור שנטען מכיל %{num_features} תכונות. באופן כללי, חלק מהדפדפנים לא יוכלו להתמודד עם הצגה של כזו כמות של נתונים. לרוב, דפדפנים עובדים באופן מיטבי בהצגת פחות מ־%{max_features} תכונות בו־זמנית: ביצוע משימות נוספות עלול לגרום לדפדפן לפעול באופן איטי או להיתקע. אם ברצונך בכל זאת להציג מידע זה, באפשרותך להציג אותו בלחיצה על הכפתור למטה."
loading: בטעינה...
manually_select: בחירת אזור אחר ידנית
notes_layer_name: עיון בהערות
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
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
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
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
hide_areas: 領域を隠す
history_for_feature: "%{feature}の履歴"
load_data: データの読み込み
- loaded_an_area_with_num_features: "%{num_features}件の地物を含む領域を読み込みました。一般に、ブラウザーによっては、この量のデータを表示するとうまく処理できないかもしれません。通常、ブラウザーは一度に%{max_features}件未満の地物を表示させるとうまく動作します。このままでは、ブラウザーが遅くなったり、反応しなくなったりします。それでもこのデータを表示したいならば、以下のボタンをクリックしてください。"
loading: 読み込み中...
manually_select: ドラッグして別の領域を選択
notes_layer_name: メモを閲覧
hide_areas: 지역 숨기기
history_for_feature: "%{feature}의 역사"
load_data: 데이터 불러오기
- loaded_an_area_with_num_features: 당신은 특성을 가진 지역 %{num_features}개를 불러왔습니다. 일반적으로, 일부 브라우저에서는 이 데이터 개수를 모두 처리하지 못할 수도 있습니다. 일반적으로, 브라우저들은 대개 특성 %{max_features}개 이하를 처리하여 보여줄 수 있습니다. 그렇지 않은 경우, 브라우저의 속도가 저하되거나 브라우저의 반응이 느려질 수 있습니다. 여전히 이 데이터를 표시하려면, 아래의 버튼을 클릭하세요.
loading: 불러오는 중...
manually_select: 다른 지역 선택
notes_layer_name: 참고 찾아보기
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
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
hide_areas: Скриј подрачја
history_for_feature: Историја за %{feature}
load_data: Вчитај ги податоците
- loaded_an_area_with_num_features: "Вчитавте простор што содржи %{num_features} елементи. Некои прелистувачи не можат да се справат со толку податоци. Начелно, прелистувачите работат најдобро при помалку од %{max_features} елементи наеднаш: ако правите нешто друго прелистувачот ќе ви биде бавен/пасивен. Ако и покрај тоа сакате да се прикажат овие податоци, тогаш стиснете на копчето подолу."
loading: Вчитувам...
manually_select: Рачно изберете друга површина
notes_layer_name: Прелистај белешки
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
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
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
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
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
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
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
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:
hide_areas: Скрыть области
history_for_feature: История %{feature}
load_data: Загрузить данные
- loaded_an_area_with_num_features: Вы загрузили область, которая содержит %{num_features} объектов. Некоторые браузеры могут не справиться с отображением такого количества данных. Обычно браузеры могут обрабатывать до %{max_features} объектов. Загрузка большего числа может замедлить ваш браузер или привести к его зависанию. Если вы всё равно хотите отобразить эти данные, нажмите на кнопку ниже.
loading: Загрузка...
manually_select: Выделить другую область
notes_layer_name: Просмотр заметок
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
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
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:
hide_areas: Сакриј подручја
history_for_feature: Историја за %{feature}
load_data: Учитај податке
- loaded_an_area_with_num_features: "Учитали сте подручје које садржи %{num_features} могућности. Неки прегледачи се не могу носити с толиком количином података. Они најбоље раде када приказују мање од %{max_features} могућности истовремено: ако радите још нешто, то може успорити прегледач или га закочити. Ако сте сигурни да желите да прикажете ове податке, можете то урадити кликом на дугме испод."
loading: Учитавам…
manually_select: Ручно изаберите друго подручје
object_list:
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
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:
hide_areas: Приховати ділянки
history_for_feature: Історія %{feature}
load_data: Завантажити Дані
- loaded_an_area_with_num_features: "Ви завантажили ділянку, яка містить %{num_features} об’єктів. Загалом, деякі оглядачі можуть не впоратися з відображенням такої кількості даних. Зазвичай, оглядачі працюють краще, коли водночас показується не більше %{max_features} об'єктів: якщо ж ви робите інакше, це може спричинити сповільнення чи взагалі відсутність відгуку у вашому оглядачі. Коли ви впевнені, що слід показати ці дані, можете натиснути кнопку нижче."
loading: Завантаження…
manually_select: Виберіть іншу ділянку
notes_layer_name: Огляд нотаток
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ú
hide_areas: 隐藏区域
history_for_feature: "%{feature}的历史"
load_data: 载入数据
- loaded_an_area_with_num_features: 你已经载入一个包含%{num_features}个特征的区域。一般而言,一些浏览器无法正常显示这一数量的数据。通常,浏览器可以较好地显示少于%{max_features}个特征,超过这一数量则会使你的浏览器变慢/无响应。如果你确定你想要显示这些数据,请单击下面的按钮。
loading: 正在载入...
manually_select: 手动选择不同的区域
notes_layer_name: 浏览注释
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]
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
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
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
# 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
##
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
# 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
end
get type, {:id => id}
assert_response :success
- assert_template type
+ assert_template template
end
end
{ :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
# -----------------------
##
# 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
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
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
#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
# 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"
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
# 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
# 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
##
# 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" }
)
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
# 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(
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
##
)
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(
get :index
assert_response :success
assert_template 'index'
- assert_site_partials
end
def test_index_redirect
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
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
##
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
##
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
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
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
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
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"
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"
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
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"
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"
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
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
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
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
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
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
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
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
##
# 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
--- /dev/null
+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
# 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
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
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
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
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
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
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
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
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
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
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
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
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
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)
assert_response :redirect
follow_redirect!
assert_response :success
- assert_template 'changeset/list'
+ assert_template 'changeset/history'
end
def test_login_openid_cancel
--- /dev/null
+/**
+* @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 = '<xyz></xyz>';
+ //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<style>' + cssText + '</style>';
+ 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<l;i++){
+ clone.createElement(elems[i]);
+ }
+ return clone;
+ }
+
+ /**
+ * Shivs the `createElement` and `createDocumentFragment` methods of the document.
+ * @private
+ * @param {Document|DocumentFragment} ownerDocument The document.
+ * @param {Object} data of the document.
+ */
+ function shivMethods(ownerDocument, data) {
+ if (!data.cache) {
+ data.cache = {};
+ data.createElem = ownerDocument.createElement;
+ data.createFrag = ownerDocument.createDocumentFragment;
+ data.frag = data.createFrag();
+ }
+
+
+ ownerDocument.createElement = function(nodeName) {
+ //abort shiv
+ if (!html5.shivMethods) {
+ return data.createElem(nodeName);
+ }
+ return createElement(nodeName, ownerDocument, data);
+ };
+
+ ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' +
+ 'var n=f.cloneNode(),c=n.createElement;' +
+ 'h.shivMethods&&(' +
+ // unroll the `createElement` calls
+ getElements().join().replace(/[\w\-]+/g, function(nodeName) {
+ data.createElem(nodeName);
+ data.frag.createElement(nodeName);
+ return 'c("' + nodeName + '")';
+ }) +
+ ');return n}'
+ )(html5, data.frag);
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * Shivs the given document.
+ * @memberOf html5
+ * @param {Document} ownerDocument The document to shiv.
+ * @returns {Document} The shived document.
+ */
+ function shivDocument(ownerDocument) {
+ if (!ownerDocument) {
+ ownerDocument = document;
+ }
+ var data = getExpandoData(ownerDocument);
+
+ if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) {
+ data.hasCSS = !!addStyleSheet(ownerDocument,
+ // corrects block display not defined in IE6/7/8/9
+ 'article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}' +
+ // adds styling not present in IE6/7/8/9
+ 'mark{background:#FF0;color:#000}' +
+ // hides non-rendered elements
+ 'template{display:none}'
+ );
+ }
+ if (!supportsUnknownElements) {
+ shivMethods(ownerDocument, data);
+ }
+ return ownerDocument;
+ }
+
+ /*--------------------------------------------------------------------------*/
+
+ /**
+ * The `html5` object is exposed so that more elements can be shived and
+ * existing shiving can be detected on iframes.
+ * @type Object
+ * @example
+ *
+ * // options can be changed before the script is included
+ * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false };
+ */
+ var html5 = {
+
+ /**
+ * An array or space separated string of node names of the elements to shiv.
+ * @memberOf html5
+ * @type Array|String
+ */
+ 'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video',
+
+ /**
+ * current version of html5shiv
+ */
+ 'version': version,
+
+ /**
+ * A flag to indicate that the HTML5 style sheet should be inserted.
+ * @memberOf html5
+ * @type Boolean
+ */
+ 'shivCSS': (options.shivCSS !== false),
+
+ /**
+ * Is equal to true if a browser supports creating unknown/HTML5 elements
+ * @memberOf html5
+ * @type boolean
+ */
+ 'supportsUnknownElements': supportsUnknownElements,
+
+ /**
+ * A flag to indicate that the document's `createElement` and `createDocumentFragment`
+ * methods should be overwritten.
+ * @memberOf html5
+ * @type Boolean
+ */
+ 'shivMethods': (options.shivMethods !== false),
+
+ /**
+ * A string to describe the type of `html5` object ("default" or "default print").
+ * @memberOf html5
+ * @type String
+ */
+ 'type': 'default',
+
+ // shivs the document according to the specified `html5` object options
+ 'shivDocument': shivDocument,
+
+ //creates a shived element
+ createElement: createElement,
+
+ //creates a shived documentFragment
+ createDocumentFragment: createDocumentFragment
+ };
+
+ /*--------------------------------------------------------------------------*/
+
+ // expose html5
+ window.html5 = html5;
+
+ // shiv the document
+ shivDocument(document);
+
+}(this, document));
+++ /dev/null
-(function(window) {
- var HAS_HASHCHANGE = (function() {
- var doc_mode = window.documentMode;
- return ('onhashchange' in window) &&
- (doc_mode === undefined || doc_mode > 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);
});
-}(window, document));
\ No newline at end of file
+}(window, document));