From: Tom Hughes Date: Thu, 20 Sep 2012 15:01:24 +0000 (+0100) Subject: Merge branch 'master' into openstreetbugs X-Git-Tag: live~5616^2~103 X-Git-Url: https://git.openstreetmap.org./rails.git/commitdiff_plain/4d91fe3dd95c1058cb8d24fd4c900223e30b9059?hp=ea63736b5c1b6e1d1adbf043f025cc9cb4171bcb Merge branch 'master' into openstreetbugs Conflicts: Gemfile app/helpers/application_helper.rb app/views/site/index.html.erb --- diff --git a/Gemfile b/Gemfile index 25b10fe7b..5193881af 100644 --- a/Gemfile +++ b/Gemfile @@ -24,14 +24,12 @@ gem 'composite_primary_keys', '>= 5.0.8' gem 'http_accept_language', '>= 1.0.2' gem 'paperclip', '~> 2.0' gem 'deadlock_retry', '>= 1.2.0' +gem 'i18n-js', '>= 3.0.0.rc2' gem 'jsonify-rails' # We need ruby-openid 2.2.0 or later for ruby 1.9 support gem 'ruby-openid', '>= 2.2.0' -# Browser detection support -gem 'browser' - # Markdown formatting support gem 'redcarpet' diff --git a/Gemfile.lock b/Gemfile.lock index 158694564..666b6a094 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -31,9 +31,8 @@ GEM multi_json (~> 1.0) arel (3.0.2) bigdecimal (1.1.0) - browser (0.1.4) - builder (3.0.0) - cocaine (0.2.1) + builder (3.0.3) + cocaine (0.3.0) coffee-rails (3.2.2) coffee-script (>= 2.2.0) railties (~> 3.2.0) @@ -55,10 +54,12 @@ GEM http_accept_language (1.0.2) httpauth (0.1) httpclient (2.2.7) - i18n (0.6.0) + i18n (0.6.1) + i18n-js (3.0.0.rc2) + i18n iconv (0.1) journey (1.0.4) - jquery-rails (2.1.1) + jquery-rails (2.1.2) railties (>= 3.1.0, < 5.0) thor (~> 0.14) json (1.7.5) @@ -75,13 +76,13 @@ GEM i18n (>= 0.4.0) mime-types (~> 1.16) treetop (~> 1.4.8) - memcached (1.4.3) + memcached (1.4.5) mime-types (1.19) - minitest (3.3.0) + minitest (3.4.0) multi_json (1.3.6) multipart-post (1.1.5) nokogiri (1.5.5) - oauth (0.4.6) + oauth (0.4.7) oauth-plugin (0.4.1) multi_json oauth (~> 0.4.4) @@ -100,7 +101,7 @@ GEM activesupport (>= 2.3.2) cocaine (>= 0.0.2) mime-types - pg (0.14.0) + pg (0.14.1) polyglot (0.3.3) rack (1.4.1) rack-cache (1.2) @@ -120,7 +121,7 @@ GEM activesupport (= 3.2.8) bundler (~> 1.0) railties (= 3.2.8) - rails-i18n (0.6.5) + rails-i18n (0.6.6) i18n (~> 0.5) railties (3.2.8) actionpack (= 3.2.8) @@ -150,14 +151,14 @@ GEM libv8 (~> 3.3.10) thor (0.16.0) tilt (1.3.3) - timecop (0.4.5) + timecop (0.5.1) treetop (1.4.10) polyglot polyglot (>= 0.3.1) tzinfo (0.3.33) - uglifier (1.2.7) + uglifier (1.3.0) execjs (>= 0.3.0) - multi_json (~> 1.3) + multi_json (~> 1.0, >= 1.0.2) validates_email_format_of (1.5.3) PLATFORMS @@ -166,7 +167,6 @@ PLATFORMS DEPENDENCIES SystemTimer (>= 1.1.3) bigdecimal - browser coffee-rails (~> 3.2.1) composite_primary_keys (>= 5.0.8) deadlock_retry (>= 1.2.0) @@ -174,6 +174,7 @@ DEPENDENCIES htmlentities http_accept_language (>= 1.0.2) httpclient + i18n-js (>= 3.0.0.rc2) iconv jquery-rails jsonify-rails diff --git a/app/assets/images/key/osmarender/admin.png b/app/assets/images/key/osmarender/admin.png deleted file mode 100644 index 80a10f20c..000000000 Binary files a/app/assets/images/key/osmarender/admin.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/allotments.png b/app/assets/images/key/osmarender/allotments.png deleted file mode 100644 index ed1af15bf..000000000 Binary files a/app/assets/images/key/osmarender/allotments.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/bridleway.png b/app/assets/images/key/osmarender/bridleway.png deleted file mode 100644 index 3652d188d..000000000 Binary files a/app/assets/images/key/osmarender/bridleway.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/brownfield.png b/app/assets/images/key/osmarender/brownfield.png deleted file mode 100644 index b1f348519..000000000 Binary files a/app/assets/images/key/osmarender/brownfield.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/building.png b/app/assets/images/key/osmarender/building.png deleted file mode 100644 index e2b9902fc..000000000 Binary files a/app/assets/images/key/osmarender/building.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/byway.png b/app/assets/images/key/osmarender/byway.png deleted file mode 100644 index 2791234ac..000000000 Binary files a/app/assets/images/key/osmarender/byway.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/cemetery.png b/app/assets/images/key/osmarender/cemetery.png deleted file mode 100644 index fa5b98461..000000000 Binary files a/app/assets/images/key/osmarender/cemetery.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/centre.png b/app/assets/images/key/osmarender/centre.png deleted file mode 100644 index 0ac055eb9..000000000 Binary files a/app/assets/images/key/osmarender/centre.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/commercial.png b/app/assets/images/key/osmarender/commercial.png deleted file mode 100644 index 2b9bac942..000000000 Binary files a/app/assets/images/key/osmarender/commercial.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/common.png b/app/assets/images/key/osmarender/common.png deleted file mode 100644 index ed1af15bf..000000000 Binary files a/app/assets/images/key/osmarender/common.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/cycleway.png b/app/assets/images/key/osmarender/cycleway.png deleted file mode 100644 index 7b37a80ea..000000000 Binary files a/app/assets/images/key/osmarender/cycleway.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/farm.png b/app/assets/images/key/osmarender/farm.png deleted file mode 100644 index ed1af15bf..000000000 Binary files a/app/assets/images/key/osmarender/farm.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/footway.png b/app/assets/images/key/osmarender/footway.png deleted file mode 100644 index dd9d9124c..000000000 Binary files a/app/assets/images/key/osmarender/footway.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/forest.png b/app/assets/images/key/osmarender/forest.png deleted file mode 100644 index 5fa90f1e6..000000000 Binary files a/app/assets/images/key/osmarender/forest.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/heathland.png b/app/assets/images/key/osmarender/heathland.png deleted file mode 100644 index 07db3315d..000000000 Binary files a/app/assets/images/key/osmarender/heathland.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/industrial.png b/app/assets/images/key/osmarender/industrial.png deleted file mode 100644 index b1f348519..000000000 Binary files a/app/assets/images/key/osmarender/industrial.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/lake.png b/app/assets/images/key/osmarender/lake.png deleted file mode 100644 index 4d80a033c..000000000 Binary files a/app/assets/images/key/osmarender/lake.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/mapkey.png b/app/assets/images/key/osmarender/mapkey.png deleted file mode 100644 index 64c858fb2..000000000 Binary files a/app/assets/images/key/osmarender/mapkey.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/military.png b/app/assets/images/key/osmarender/military.png deleted file mode 100644 index 40fa3cd9f..000000000 Binary files a/app/assets/images/key/osmarender/military.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/motorway.png b/app/assets/images/key/osmarender/motorway.png deleted file mode 100644 index 456eae5f4..000000000 Binary files a/app/assets/images/key/osmarender/motorway.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/park.png b/app/assets/images/key/osmarender/park.png deleted file mode 100644 index e9a3448b7..000000000 Binary files a/app/assets/images/key/osmarender/park.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/pitch.png b/app/assets/images/key/osmarender/pitch.png deleted file mode 100644 index e9a3448b7..000000000 Binary files a/app/assets/images/key/osmarender/pitch.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/primary.png b/app/assets/images/key/osmarender/primary.png deleted file mode 100644 index caf298d63..000000000 Binary files a/app/assets/images/key/osmarender/primary.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/rail.png b/app/assets/images/key/osmarender/rail.png deleted file mode 100644 index 21f0c9f61..000000000 Binary files a/app/assets/images/key/osmarender/rail.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/reserve.png b/app/assets/images/key/osmarender/reserve.png deleted file mode 100644 index ff15c8259..000000000 Binary files a/app/assets/images/key/osmarender/reserve.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/resident.png b/app/assets/images/key/osmarender/resident.png deleted file mode 100644 index 9be0e4903..000000000 Binary files a/app/assets/images/key/osmarender/resident.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/retail.png b/app/assets/images/key/osmarender/retail.png deleted file mode 100644 index 38c330580..000000000 Binary files a/app/assets/images/key/osmarender/retail.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/school.png b/app/assets/images/key/osmarender/school.png deleted file mode 100644 index a80f78bf4..000000000 Binary files a/app/assets/images/key/osmarender/school.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/secondary.png b/app/assets/images/key/osmarender/secondary.png deleted file mode 100644 index 2695a4d5b..000000000 Binary files a/app/assets/images/key/osmarender/secondary.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/station.png b/app/assets/images/key/osmarender/station.png deleted file mode 100644 index 0b1fae27d..000000000 Binary files a/app/assets/images/key/osmarender/station.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/subway.png b/app/assets/images/key/osmarender/subway.png deleted file mode 100644 index c225c2af6..000000000 Binary files a/app/assets/images/key/osmarender/subway.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/summit.png b/app/assets/images/key/osmarender/summit.png deleted file mode 100644 index f777f6ea3..000000000 Binary files a/app/assets/images/key/osmarender/summit.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/tourist.png b/app/assets/images/key/osmarender/tourist.png deleted file mode 100644 index ceb7b19a7..000000000 Binary files a/app/assets/images/key/osmarender/tourist.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/track.png b/app/assets/images/key/osmarender/track.png deleted file mode 100644 index 3c67f5438..000000000 Binary files a/app/assets/images/key/osmarender/track.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/tram.png b/app/assets/images/key/osmarender/tram.png deleted file mode 100644 index 4dc979de3..000000000 Binary files a/app/assets/images/key/osmarender/tram.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/trunk.png b/app/assets/images/key/osmarender/trunk.png deleted file mode 100644 index c28b77571..000000000 Binary files a/app/assets/images/key/osmarender/trunk.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/unsurfaced.png b/app/assets/images/key/osmarender/unsurfaced.png deleted file mode 100644 index 6837c48ab..000000000 Binary files a/app/assets/images/key/osmarender/unsurfaced.png and /dev/null differ diff --git a/app/assets/images/key/osmarender/wood.png b/app/assets/images/key/osmarender/wood.png deleted file mode 100644 index 5fa90f1e6..000000000 Binary files a/app/assets/images/key/osmarender/wood.png and /dev/null differ diff --git a/app/assets/images/sotm.png b/app/assets/images/sotm.png deleted file mode 100644 index 169b8071d..000000000 Binary files a/app/assets/images/sotm.png and /dev/null differ diff --git a/app/assets/images/sotmpdx.png b/app/assets/images/sotmpdx.png new file mode 100755 index 000000000..73d0a9d06 Binary files /dev/null and b/app/assets/images/sotmpdx.png differ diff --git a/app/assets/javascripts/site.js b/app/assets/javascripts/application.js similarity index 59% rename from app/assets/javascripts/site.js rename to app/assets/javascripts/application.js index 311798aa5..71eb71711 100644 --- a/app/assets/javascripts/site.js +++ b/app/assets/javascripts/application.js @@ -2,23 +2,46 @@ //= require jquery_ujs //= require jquery.autogrowtextarea //= require jquery.timers +//= require jquery.cookie +//= require augment +//= require openlayers +//= require i18n/translations +//= require globals +//= require params +//= require piwik +//= require browse +//= require export +//= require map +//= require key +//= require menu +//= require sidebar +//= require richtext +//= require resize +//= require notes + +function zoomPrecision(zoom) { + var decimals = Math.pow(10, Math.floor(zoom/3)); + return function(x) { + return Math.round(x * decimals) / decimals; + }; +} /* * Called as the user scrolls/zooms around to aniplate hrefs of the * view tab and various other links */ function updatelinks(lon,lat,zoom,layers,minlon,minlat,maxlon,maxlat,objtype,objid) { - var decimals = Math.pow(10, Math.floor(zoom/3)); + var toPrecision = zoomPrecision(zoom); var node; - lat = Math.round(lat * decimals) / decimals; - lon = Math.round(lon * decimals) / decimals; + lat = toPrecision(lat); + lon = toPrecision(lon); if (minlon) { - minlon = Math.round(minlon * decimals) / decimals; - minlat = Math.round(minlat * decimals) / decimals; - maxlon = Math.round(maxlon * decimals) / decimals; - maxlat = Math.round(maxlat * decimals) / decimals; + minlon = toPrecision(minlon); + minlat = toPrecision(minlat); + maxlon = toPrecision(maxlon); + maxlat = toPrecision(maxlat); } $(".geolink").each(function (index, link) { @@ -40,25 +63,21 @@ function updatelinks(lon,lat,zoom,layers,minlon,minlat,maxlon,maxlat,objtype,obj args[objtype] = objid; } - var classes = $(link).attr("class").split(" "); - - $(classes).each(function (index, classname) { - if (match = classname.match(/^minzoom([0-9]+)$/)) { - var minzoom = match[1]; + var minzoom = $(link).data("minzoom"); + if (minzoom) { var name = link.id.replace(/anchor$/, ""); $(link).off("click.minzoom"); if (zoom >= minzoom) { - $(link).attr("title", i18n("javascripts.site." + name + "_tooltip")); + $(link).attr("title", I18n.t("javascripts.site." + name + "_tooltip")); $(link).removeClass("disabled"); } else { - $(link).on("click.minzoom", function () { alert(i18n("javascripts.site." + name + "_zoom_alert")); return false; }); - $(link).attr("title", i18n("javascripts.site." + name + "_disabled_tooltip")); + $(link).on("click.minzoom", function () { alert(I18n.t("javascripts.site." + name + "_zoom_alert")); return false; }); + $(link).attr("title", I18n.t("javascripts.site." + name + "_disabled_tooltip")); $(link).addClass("disabled"); } - } - }); + } link.href = setArgs(link.href, args); }); @@ -144,26 +163,6 @@ function setArgs(url, args) { return url.replace(/\?.*$/, "") + "?" + queryitems.join("&"); } -/* - * Called to interpolate JavaScript variables in strings using a - * similar syntax to rails I18n string interpolation - the only - * difference is that [[foo]] is the placeholder syntax instead - * of {{foo}} which allows the same string to be processed by both - * rails and then later by javascript. - */ -function i18n(string, keys) { - string = i18n_strings[string] || string; - - for (var key in keys) { - var re_key = '\\[\\[' + key + '\\]\\]'; - var re = new RegExp(re_key, "g"); - - string = string.replace(re, keys[key]); - } - - return string; -} - /* * Called to interlace the bits in x and y, making a Morton code. */ @@ -208,62 +207,18 @@ function makeShortCode(lat, lon, zoom) { } /* - * Click handler to switch a rich text control to preview mode + * Forms which have been cached by rails may have he wrong + * authenticity token, so patch up any forms with the correct + * token taken from the page header. */ -function previewRichtext(event) { - var editor = $(this).parents(".richtext_container").find("textarea"); - var preview = $(this).parents(".richtext_container").find(".richtext_preview"); - var width = editor.outerWidth() - preview.outerWidth() + preview.innerWidth(); - var minHeight = editor.outerHeight() - preview.outerHeight() + preview.innerHeight(); - - if (preview.contents().length == 0) { - preview.oneTime(500, "loading", function () { - preview.addClass("loading"); - }); - - preview.load(editor.attr("data-preview-url"), { text: editor.val() }, function () { - preview.stopTime("loading"); - preview.removeClass("loading"); - }); - } - - editor.hide(); - preview.width(width); - preview.css("min-height", minHeight + "px"); - preview.show(); - - $(this).siblings(".richtext_doedit").prop("disabled", false); - $(this).prop("disabled", true); - - event.preventDefault(); -} - -/* - * Click handler to switch a rich text control to edit mode - */ -function editRichtext(event) { - var editor = $(this).parents(".richtext_container").find("textarea"); - var preview = $(this).parents(".richtext_container").find(".richtext_preview"); - - preview.hide(); - editor.show(); - - $(this).siblings(".richtext_dopreview").prop("disabled", false); - $(this).prop("disabled", true); - - event.preventDefault(); -} +$(document).ready(function () { + var auth_token = $("meta[name=csrf-token]").attr("content"); + $("form input[name=authenticity_token]").val(auth_token); +}); /* - * Setup any rich text controls + * Enable auto expansion for all text areas */ $(document).ready(function () { - $(".richtext_preview").hide(); - $(".richtext_content textarea").change(function () { - $(this).parents(".richtext_container").find(".richtext_preview").empty(); - }); - $(".richtext_doedit").prop("disabled", true); - $(".richtext_dopreview").prop("disabled", false); - $(".richtext_doedit").click(editRichtext); - $(".richtext_dopreview").click(previewRichtext); + $("textarea").autoGrow(); }); diff --git a/app/assets/javascripts/browse.js b/app/assets/javascripts/browse.js new file mode 100644 index 000000000..769cc112e --- /dev/null +++ b/app/assets/javascripts/browse.js @@ -0,0 +1,549 @@ +function startBrowse(sidebarHtml) { + var browseBoxControl; + var browseMode = "auto"; + var browseBounds; + var browseFeatureList; + var browseActiveFeature; + var browseDataLayer; + var browseSelectControl; + var browseObjectList; + var areasHidden = false; + + OpenLayers.Feature.Vector.style['default'].strokeWidth = 3; + OpenLayers.Feature.Vector.style['default'].cursor = "pointer"; + + map.dataLayer.active = true; + + $("#sidebar_title").html(I18n.t('browse.start_rjs.data_frame_title')); + $("#sidebar_content").html(sidebarHtml); + + openSidebar(); + + var vectors = new OpenLayers.Layer.Vector(); + + browseBoxControl = new OpenLayers.Control.DrawFeature(vectors, OpenLayers.Handler.RegularPolygon, { + handlerOptions: { + sides: 4, + snapAngle: 90, + irregular: true, + persist: true + } + }); + browseBoxControl.handler.callbacks.done = endDrag; + map.addControl(browseBoxControl); + + map.events.register("moveend", map, updateData); + map.events.triggerEvent("moveend"); + + $("#browse_select_view").click(useMap); + + $("#browse_select_box").click(startDrag); + + $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.hide_areas')); + $("#browse_hide_areas_box").show(); + $("#browse_hide_areas_box").click(hideAreas); + + function updateData() { + if (browseMode == "auto") { + if (map.getZoom() >= 15) { + useMap(false); + } else { + setStatus(I18n.t('browse.start_rjs.zoom_or_select')); + } + } + } + + $("#sidebar").one("closed", function () { + if (map.dataLayer.active) { + map.dataLayer.active = false; + + if (browseSelectControl) { + browseSelectControl.destroy(); + browseSelectControl = null; + } + + if (browseBoxControl) { + browseBoxControl.destroy(); + browseBoxControl = null; + } + + if (browseActiveFeature) { + browseActiveFeature.destroy(); + browseActiveFeature = null; + } + + if (browseDataLayer) { + browseDataLayer.destroy(); + browseDataLayer = null; + } + + map.dataLayer.setVisibility(false); + map.events.unregister("moveend", map, updateData); + } + }); + + function startDrag() { + $("#browse_select_box").html(I18n.t('browse.start_rjs.drag_a_box')); + + browseBoxControl.activate(); + + return false; + } + + function useMap(reload) { + var bounds = map.getExtent(); + var projected = bounds.clone().transform(map.getProjectionObject(), epsg4326); + + if (!browseBounds || !browseBounds.containsBounds(projected)) { + var center = bounds.getCenterLonLat(); + var tileWidth = bounds.getWidth() * 1.2; + var tileHeight = bounds.getHeight() * 1.2; + var tileBounds = new OpenLayers.Bounds(center.lon - (tileWidth / 2), + center.lat - (tileHeight / 2), + center.lon + (tileWidth / 2), + center.lat + (tileHeight / 2)); + + browseBounds = tileBounds; + getData(tileBounds, reload); + + browseMode = "auto"; + + $("#browse_select_view").hide(); + } + + return false; + } + + function hideAreas() { + $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.show_areas')); + $("#browse_hide_areas_box").show(); + $("#browse_hide_areas_box").click(showAreas); + + areasHidden = true; + + useMap(true); + } + + function showAreas() { + $("#browse_hide_areas_box").html(I18n.t('browse.start_rjs.hide_areas')); + $("#browse_hide_areas_box").show(); + $("#browse_hide_areas_box").click(hideAreas); + + areasHidden = false; + + useMap(true); + } + + function endDrag(bbox) { + var bounds = bbox.getBounds(); + var projected = bounds.clone().transform(map.getProjectionObject(), epsg4326); + + browseBoxControl.deactivate(); + browseBounds = projected; + getData(bounds); + + browseMode = "manual"; + + $("#browse_select_box").html(I18n.t('browse.start_rjs.manually_select')); + $("#browse_select_view").show(); + } + + 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); + } + + function customDataLoader(resp, options) { + if (map.dataLayer.active) { + var request = resp.priv; + var doc = request.responseXML; + + if (!doc || !doc.documentElement) { + doc = request.responseText; + } + + resp.features = this.format.read(doc); + + if (!this.maxFeatures || resp.features.length <= this.maxFeatures) { + options.callback.call(options.scope, resp); + } else { + displayFeatureWarning(resp.features.length, this.maxFeatures, function () { + options.callback.call(options.scope, resp); + }); + } + } + } + + function getData(bounds, reload) { + var projected = bounds.clone().transform(new OpenLayers.Projection("EPSG:900913"), new OpenLayers.Projection("EPSG:4326")); + var size = projected.getWidth() * projected.getHeight(); + + 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 })); + } else { + loadData("/api/" + OSM.API_VERSION + "/map?bbox=" + projected.toBBOX(), reload); + } + } + + function loadData(url, reload) { + setStatus(I18n.t('browse.start_rjs.loading')); + + $("#browse_content").empty(); + + var formatOptions = { + checkTags: true, + interestingTagsExclude: ['source','source_ref','source:ref','history','attribution','created_by','tiger:county','tiger:tlid','tiger:upload_uuid'] + }; + + if (areasHidden) formatOptions.areaTags = []; + + if (!browseDataLayer || reload) { + var style = new OpenLayers.Style(); + + style.addRules([new OpenLayers.Rule({ + symbolizer: { + Polygon: { fillColor: '#ff0000', strokeColor: '#ff0000' }, + Line: { fillColor: '#ffff00', strokeColor: '#000000', strokeOpacity: '0.4' }, + Point: { fillColor: '#00ff00', strokeColor: '#00ff00' } + } + })]); + + if (browseDataLayer) browseDataLayer.destroyFeatures(); + + /* + * Modern browsers are quite happy showing far more than 100 features in + * the data browser, so increase the limit to 2000 by default, but keep + * it restricted to 500 for IE8 and 100 for older IEs. + */ + var maxFeatures = 2000; + + /*@cc_on + if (navigator.appVersion < 8) { + maxFeatures = 100; + } else if (navigator.appVersion < 9) { + maxFeatures = 500; + } + @*/ + + browseDataLayer = new OpenLayers.Layer.Vector("Data", { + strategies: [ + new OpenLayers.Strategy.Fixed() + ], + protocol: new OpenLayers.Protocol.HTTP({ + url: url, + format: new OpenLayers.Format.OSM(formatOptions), + maxFeatures: maxFeatures, + handleRead: customDataLoader + }), + projection: new OpenLayers.Projection("EPSG:4326"), + displayInLayerSwitcher: false, + styleMap: new OpenLayers.StyleMap({ + 'default': style, + 'select': { strokeColor: '#0000ff', strokeWidth: 8 } + }) + }); + browseDataLayer.events.register("loadend", browseDataLayer, dataLoaded ); + map.addLayer(browseDataLayer); + + browseSelectControl = new OpenLayers.Control.SelectFeature(browseDataLayer, { onSelect: onFeatureSelect }); + browseSelectControl.handlers.feature.stopDown = false; + browseSelectControl.handlers.feature.stopUp = false; + map.addControl(browseSelectControl); + browseSelectControl.activate(); + } else { + browseDataLayer.destroyFeatures(); + browseDataLayer.refresh({ url: url }); + } + + browseActiveFeature = null; + } + + function dataLoaded() { + if (this.map.dataLayer.active) { + clearStatus(); + + browseObjectList = document.createElement("div"); + + var heading = document.createElement("p"); + heading.className = "browse_heading"; + heading.appendChild(document.createTextNode(I18n.t('browse.start_rjs.object_list.heading'))); + browseObjectList.appendChild(heading); + + var list = document.createElement("ul"); + + for (var i = 0; i < this.features.length; i++) { + var feature = this.features[i]; + + // Type, for linking + var type = featureType(feature); + var typeName = featureTypeName(feature); + var li = document.createElement("li"); + li.appendChild(document.createTextNode(typeName + " ")); + + // Link, for viewing in the tab + var link = document.createElement("a"); + link.href = "/browse/" + type + "/" + feature.osm_id; + var name = featureName(feature); + link.appendChild(document.createTextNode(name)); + link.feature = feature; + link.onclick = OpenLayers.Function.bind(viewFeatureLink, link); + li.appendChild(link); + + list.appendChild(li); + } + + browseObjectList.appendChild(list); + + var link = document.createElement("a"); + link.href = this.protocol.url; + link.appendChild(document.createTextNode(I18n.t('browse.start_rjs.object_list.api'))); + browseObjectList.appendChild(link); + + $("#browse_content").html(browseObjectList); + } + } + + function viewFeatureLink() { + var layer = this.feature.layer; + + for (var i = 0; i < layer.selectedFeatures.length; i++) { + var f = layer.selectedFeatures[i]; + layer.drawFeature(f, layer.styleMap.createSymbolizer(f, "default")); + } + + onFeatureSelect(this.feature); + + if (browseMode != "auto") { + map.setCenter(this.feature.geometry.getBounds().getCenterLonLat()); + } + + return false; + } + + function loadObjectList() { + $("#browse_content").empty(); + $("#browse_content").append(browseObjectList); + + return false; + } + + function onFeatureSelect(feature) { + // Unselect previously selected feature + if (browseActiveFeature) { + browseActiveFeature.layer.drawFeature( + browseActiveFeature, + browseActiveFeature.layer.styleMap.createSymbolizer(browseActiveFeature, "default") + ); + } + + // Redraw in selected style + feature.layer.drawFeature( + feature, feature.layer.styleMap.createSymbolizer(feature, "select") + ); + + // 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(); + } + + // Create a link back to the object list + var div = document.createElement("div"); + div.style.textAlign = "center"; + div.style.marginBottom = "20px"; + $("#browse_content").append(div); + var link = document.createElement("a"); + link.href = "#"; + link.onclick = loadObjectList; + link.appendChild(document.createTextNode(I18n.t('browse.start_rjs.object_list.back'))); + div.appendChild(link); + + var table = document.createElement("table"); + table.width = "100%"; + table.className = "browse_heading"; + $("#browse_content").append(table); + + var tr = document.createElement("tr"); + table.appendChild(tr); + + var heading = document.createElement("td"); + heading.appendChild(document.createTextNode(featureNameSelect(feature))); + tr.appendChild(heading); + + var td = document.createElement("td"); + td.align = "right"; + tr.appendChild(td); + + var type = featureType(feature); + var link = document.createElement("a"); + link.href = "/browse/" + type + "/" + feature.osm_id; + link.appendChild(document.createTextNode(I18n.t('browse.start_rjs.object_list.details'))); + td.appendChild(link); + + var div = document.createElement("div"); + div.className = "browse_details"; + + $("#browse_content").append(div); + + // Now the list of attributes + var ul = document.createElement("ul"); + for (var key in feature.attributes) { + var li = document.createElement("li"); + var b = document.createElement("b"); + b.appendChild(document.createTextNode(key)); + li.appendChild(b); + li.appendChild(document.createTextNode(": " + feature.attributes[key])); + ul.appendChild(li); + } + + div.appendChild(ul); + + var link = document.createElement("a"); + link.href = "/browse/" + type + "/" + feature.osm_id + "/history"; + link.appendChild(document.createTextNode(I18n.t('browse.start_rjs.show_history'))); + link.onclick = OpenLayers.Function.bind(loadHistory, { + type: type, feature: feature, link: link + }); + + div.appendChild(link); + + // Stash the currently drawn feature + browseActiveFeature = feature; + } + + function loadHistory() { + this.link.href = ""; + this.link.innerHTML = I18n.t('browse.start_rjs.wait'); + + $.ajax("/api/" + OSM.API_VERSION + "/" + this.type + "/" + this.feature.osm_id + "/history", { + complete: OpenLayers.Function.bind(displayHistory, this) + }); + + return false; + } + + function displayHistory(request) { + if (browseActiveFeature.osm_id != this.feature.osm_id || $("#browse_content").firstChild == browseObjectList) { + return false; + } + + this.link.parentNode.removeChild(this.link); + + var doc = request.responseXML; + + var table = document.createElement("table"); + table.width = "100%"; + table.className = "browse_heading"; + $("#browse_content").append(table); + + var tr = document.createElement("tr"); + table.appendChild(tr); + + var heading = document.createElement("td"); + heading.appendChild(document.createTextNode(I18n.t("browse.start_rjs.history_for_feature", { feature: featureNameHistory(this.feature) }))); + tr.appendChild(heading); + + var td = document.createElement("td"); + td.align = "right"; + tr.appendChild(td); + + var link = document.createElement("a"); + link.href = "/browse/" + this.type + "/" + this.feature.osm_id + "/history"; + link.appendChild(document.createTextNode(I18n.t('browse.start_rjs.details'))); + td.appendChild(link); + + var div = document.createElement("div"); + div.className = "browse_details"; + + var nodes = doc.getElementsByTagName(this.type); + var history = document.createElement("ul"); + for (var i = nodes.length - 1; i >= 0; i--) { + var user = nodes[i].getAttribute("user") || I18n.t('browse.start_rjs.private_user'); + var timestamp = nodes[i].getAttribute("timestamp"); + var item = document.createElement("li"); + item.appendChild(document.createTextNode(I18n.t("browse.start_rjs.edited_by_user_at_timestamp", { user: user, timestamp: timestamp }))); + history.appendChild(item); + } + div.appendChild(history); + + $("#browse_content").append(div); + } + + function featureType(feature) { + if (feature.geometry.CLASS_NAME == "OpenLayers.Geometry.Point") { + return "node"; + } else { + return "way"; + } + } + + function featureTypeName(feature) { + if (featureType(feature) == "node") { + return I18n.t('browse.start_rjs.object_list.type.node'); + } else if (featureType(feature) == "way") { + return I18n.t('browse.start_rjs.object_list.type.way'); + } + } + + function featureName(feature) { + var lang = $('html').attr('lang'); + if (feature.attributes['name:' + lang]) { + return feature.attributes['name:' + lang]; + } else if (feature.attributes.name) { + return feature.attributes.name; + } else { + return feature.osm_id; + } + } + + function featureNameSelect(feature) { + var lang = $('html').attr('lang'); + if (feature.attributes['name:' + lang]) { + return feature.attributes['name:' + lang]; + } else if (feature.attributes.name) { + return feature.attributes.name; + } else if (featureType(feature) == "node") { + return I18n.t("browse.start_rjs.object_list.selected.type.node", { id: feature.osm_id }); + } else if (featureType(feature) == "way") { + return I18n.t("browse.start_rjs.object_list.selected.type.way", { id: feature.osm_id }); + } + } + + function featureNameHistory(feature) { + var lang = $('html').attr('lang'); + if (feature.attributes['name:' + lang]) { + return feature.attributes['name:' + lang]; + } else if (feature.attributes.name) { + return feature.attributes.name; + } else if (featureType(feature) == "node") { + return I18n.t("browse.start_rjs.object_list.history.type.node", { id: feature.osm_id }); + } else if (featureType(feature) == "way") { + return I18n.t("browse.start_rjs.object_list.history.type.way", { id: feature.osm_id }); + } + } + + function setStatus(status) { + $("#browse_status").html(status); + $("#browse_status").show(); + } + + function clearStatus() { + $("#browse_status").html(""); + $("#browse_status").hide(); + } +} diff --git a/app/assets/javascripts/export.js b/app/assets/javascripts/export.js new file mode 100644 index 000000000..ae1871b50 --- /dev/null +++ b/app/assets/javascripts/export.js @@ -0,0 +1,318 @@ +function startExport(sidebarHtml) { + var vectors, + box, + transform, + markerLayer, + markerControl, + epsg4326 = new OpenLayers.Projection("EPSG:4326"), + epsg900913 = new OpenLayers.Projection("EPSG:900913"); + + vectors = new OpenLayers.Layer.Vector("Vector Layer", { + displayInLayerSwitcher: false + }); + map.addLayer(vectors); + + box = new OpenLayers.Control.DrawFeature(vectors, OpenLayers.Handler.RegularPolygon, { + handlerOptions: { + sides: 4, + snapAngle: 90, + irregular: true, + persist: true + } + }); + box.handler.callbacks.done = endDrag; + map.addControl(box); + + transform = new OpenLayers.Control.TransformFeature(vectors, { + rotate: false, + irregular: true + }); + transform.events.register("transformcomplete", transform, transformComplete); + map.addControl(transform); + + map.events.register("moveend", map, mapMoved); + map.events.register("changebaselayer", map, htmlUrlChanged); + + $("#sidebar_title").html(I18n.t('export.start_rjs.export')); + $("#sidebar_content").html(sidebarHtml); + + $("#maxlat,#minlon,#maxlon,#minlat").change(boundsChanged); + + $("#drag_box").click(startDrag); + + $("#add_marker").click(startMarker); + + $("#format_osm,#format_mapnik,#format_html").click(formatChanged); + + $("#mapnik_scale").change(mapnikSizeChanged); + + openSidebar(); + + if (map.baseLayer.name == "Mapnik") { + $("#format_mapnik").prop("checked", true); + } + + formatChanged(); + setBounds(map.getExtent()); + + $("body").removeClass("site-index").addClass("site-export"); + + $("#sidebar").one("closed", function () { + $("body").removeClass("site-export").addClass("site-index"); + + clearBox(); + clearMarker(); + map.events.unregister("moveend", map, mapMoved); + map.events.unregister("changebaselayer", map, htmlUrlChanged); + map.removeLayer(vectors); + }); + + function getMercatorBounds() { + var bounds = new OpenLayers.Bounds($("#minlon").val(), $("#minlat").val(), + $("#maxlon").val(), $("#maxlat").val()); + + return bounds.transform(epsg4326, epsg900913); + } + + function boundsChanged() { + var bounds = getMercatorBounds(); + + map.events.unregister("moveend", map, mapMoved); + map.zoomToExtent(bounds); + + clearBox(); + drawBox(bounds); + + validateControls(); + mapnikSizeChanged(); + } + + function startDrag() { + $("#drag_box").html(I18n.t('export.start_rjs.drag_a_box')); + + clearBox(); + box.activate(); + }; + + function endDrag(bbox) { + var bounds = bbox.getBounds(); + + map.events.unregister("moveend", map, mapMoved); + setBounds(bounds); + drawBox(bounds); + box.deactivate(); + validateControls(); + + $("#drag_box").html(I18n.t('export.start_rjs.manually_select')); + } + + function transformComplete(event) { + setBounds(event.feature.geometry.bounds); + validateControls(); + } + + function startMarker() { + $("#add_marker").html(I18n.t('export.start_rjs.click_add_marker')); + + if (!markerLayer) { + markerLayer = new OpenLayers.Layer.Vector("",{ + displayInLayerSwitcher: false, + style: { + externalGraphic: OpenLayers.Util.getImageLocation("marker.png"), + graphicXOffset: -10.5, + graphicYOffset: -25, + graphicWidth: 21, + graphicHeight: 25 + } + }); + map.addLayer(markerLayer); + + markerControl = new OpenLayers.Control.DrawFeature(markerLayer, OpenLayers.Handler.Point); + map.addControl(markerControl); + + markerLayer.events.on({ "featureadded": endMarker }); + } + + markerLayer.destroyFeatures(); + markerControl.activate(); + + return false; + } + + function endMarker(event) { + markerControl.deactivate(); + + $("#add_marker").html(I18n.t('export.start_rjs.change_marker')); + $("#marker_inputs").show(); + + var geom = event.feature.geometry.clone().transform(epsg900913, epsg4326); + + $("#marker_lon").val(geom.x.toFixed(5)); + $("#marker_lat").val(geom.y.toFixed(5)); + + htmlUrlChanged(); + } + + function clearMarker() { + $("#marker_lon,#marker_lat").val(""); + $("#marker_inputs").hide(); + $("#add_marker").html(I18n.t('export.start_rjs.add_marker')); + + if (markerLayer) { + markerControl.destroy(); + markerLayer.destroy(); + markerLayer = null; + markerControl = null; + } + } + + function mapMoved() { + setBounds(map.getExtent()); + validateControls(); + } + + function setBounds(bounds) { + var toPrecision = zoomPrecision(map.getZoom()); + + bounds = bounds.clone().transform(map.getProjectionObject(), epsg4326); + + $("#minlon").val(toPrecision(bounds.left)); + $("#minlat").val(toPrecision(bounds.bottom)); + $("#maxlon").val(toPrecision(bounds.right)); + $("#maxlat").val(toPrecision(bounds.top)); + + mapnikSizeChanged(); + htmlUrlChanged(); + } + + function clearBox() { + transform.deactivate(); + vectors.destroyFeatures(); + } + + function drawBox(bounds) { + var feature = new OpenLayers.Feature.Vector(bounds.toGeometry()); + + vectors.addFeatures(feature); + transform.setFeature(feature); + } + + function validateControls() { + var bounds = new OpenLayers.Bounds($("#minlon").val(), $("#minlat").val(), $("#maxlon").val(), $("#maxlat").val()); + + if (bounds.getWidth() * bounds.getHeight() > OSM.MAX_REQUEST_AREA) { + $("#export_osm_too_large").show(); + } else { + $("#export_osm_too_large").hide(); + } + + var max_scale = maxMapnikScale(); + var disabled = true; + + if ($("#format_osm").prop("checked")) { + disabled = bounds.getWidth() * bounds.getHeight() > OSM.MAX_REQUEST_AREA; + } else if ($("#format_mapnik").prop("checked")) { + disabled = $("#mapnik_scale").val() < max_scale; + } + + $("#export_commit").prop("disabled", disabled); + $("#mapnik_max_scale").html(roundScale(max_scale)); + } + + function htmlUrlChanged() { + var bounds = new OpenLayers.Bounds($("#minlon").val(), $("#minlat").val(), $("#maxlon").val(), $("#maxlat").val()); + var layerName = map.baseLayer.keyid; + var url = "http://" + OSM.SERVER_URL + "/export/embed.html?bbox=" + bounds.toBBOX() + "&layer=" + layerName; + var markerUrl = ""; + + if ($("#marker_lat").val() && $("#marker_lon").val()) { + markerUrl = "&mlat=" + $("#marker_lat").val() + "&mlon=" + $("#marker_lon").val(); + url += "&marker=" + $("#marker_lat").val() + "," + $("#marker_lon").val(); + } + + var html = ''; + + // Create "larger map" link + var center = bounds.getCenterLonLat(); + + bounds.transform(epsg4326, epsg900913); + var zoom = map.getZoomForExtent(bounds); + + var layers = getMapLayers(); + + var text = I18n.t('export.start_rjs.view_larger_map'); + var escaped = []; + + for (var i = 0; i < text.length; ++i) { + var c = text.charCodeAt(i); + escaped.push(c < 127 ? text.charAt(i) : "&#" + c + ";"); + } + + html += '
'+escaped.join("")+''; + + $("#export_html_text").val(html); + + if ($("#format_html").prop("checked")) { + $("#export_html_text").prop("selected", true); + } + } + + function formatChanged() { + $("#export_commit").show(); + + if ($("#format_osm").prop("checked")) { + $("#export_osm").show(); + } else { + $("#export_osm").hide(); + } + + if ($("#format_mapnik").prop("checked")) { + $("#mapnik_scale").val(roundScale(map.getScale())); + $("#export_mapnik").show(); + + mapnikSizeChanged(); + } else { + $("#export_mapnik").hide(); + } + + if ($("#format_html").prop("checked")) { + $("#export_html").show(); + $("#export_commit").hide(); + $("#export_html_text").prop("selected", true); + } else { + $("#export_html").hide(); + + clearMarker(); + } + + validateControls(); + } + + function maxMapnikScale() { + var bounds = getMercatorBounds(); + + return Math.floor(Math.sqrt(bounds.getWidth() * bounds.getHeight() / 0.3136)); + } + + function mapnikImageSize(scale) { + var bounds = getMercatorBounds(); + + return new OpenLayers.Size(Math.round(bounds.getWidth() / scale / 0.00028), + Math.round(bounds.getHeight() / scale / 0.00028)); + } + + function roundScale(scale) { + var precision = 5 * Math.pow(10, Math.floor(Math.LOG10E * Math.log(scale)) - 2); + + return precision * Math.ceil(scale / precision); + } + + function mapnikSizeChanged() { + var size = mapnikImageSize($("#mapnik_scale").val()); + + $("#mapnik_image_width").html(size.w); + $("#mapnik_image_height").html(size.h); + + validateControls(); + } +} diff --git a/app/assets/javascripts/globals.js.erb b/app/assets/javascripts/globals.js.erb new file mode 100644 index 000000000..3c3bd92a7 --- /dev/null +++ b/app/assets/javascripts/globals.js.erb @@ -0,0 +1,9 @@ +OSM = { +<% if defined?(PIWIK_LOCATION) and defined?(PIWIK_SITE) %> + PIWIK_LOCATION: <%= PIWIK_LOCATION.to_json %>, + PIWIK_SITE: <%= PIWIK_SITE.to_json %>, +<% end %> + MAX_REQUEST_AREA: <%= MAX_REQUEST_AREA.to_json %>, + SERVER_URL: <%= SERVER_URL.to_json %>, + API_VERSION: <%= API_VERSION.to_json %> +}; diff --git a/app/assets/javascripts/key.js b/app/assets/javascripts/key.js new file mode 100644 index 000000000..1e4138b70 --- /dev/null +++ b/app/assets/javascripts/key.js @@ -0,0 +1,36 @@ +$(document).ready(function () { + $("#open_map_key").click(function (e) { + var url = $(this).attr('href'), + title = $(this).text(); + + function updateMapKey() { + var mapLayer = map.baseLayer.keyid, + mapZoom = map.getZoom(); + + $(".mapkey-table-entry").each(function () { + var data = $(this).data(); + + if (mapLayer == data.layer && + mapZoom >= data.zoomMin && mapZoom <= data.zoomMax) { + $(this).show(); + } else { + $(this).hide(); + } + }); + } + + $("#sidebar_content").load(url, updateMapKey); + + openSidebar({ title: title }); + + $("#sidebar").one("closed", function () { + map.events.unregister("zoomend", map, updateMapKey); + map.events.unregister("changelayer", map, updateMapKey); + }); + + map.events.register("zoomend", map, updateMapKey); + map.events.register("changelayer", map, updateMapKey); + + e.preventDefault(); + }); +}); diff --git a/app/assets/javascripts/map.js.erb b/app/assets/javascripts/map.js.erb index 50b0fe441..8aa9868b3 100644 --- a/app/assets/javascripts/map.js.erb +++ b/app/assets/javascripts/map.js.erb @@ -22,7 +22,7 @@ function createMap(divName, options) { theme: "<%= asset_path 'theme/openstreetmap/style.css' %>" }); - var mapnik = new OpenLayers.Layer.OSM.Mapnik(i18n("javascripts.map.base.standard"), { + var mapnik = new OpenLayers.Layer.OSM.Mapnik(I18n.t("javascripts.map.base.standard"), { attribution: "", keyid: "mapnik", displayOutsideMaxExtent: true, @@ -31,7 +31,7 @@ function createMap(divName, options) { }); map.addLayer(mapnik); - var cyclemap = new OpenLayers.Layer.OSM.CycleMap(i18n("javascripts.map.base.cycle_map"), { + var cyclemap = new OpenLayers.Layer.OSM.CycleMap(I18n.t("javascripts.map.base.cycle_map"), { attribution: "Tiles courtesy of Andy Allan", keyid: "cyclemap", displayOutsideMaxExtent: true, @@ -40,7 +40,7 @@ function createMap(divName, options) { }); map.addLayer(cyclemap); - var transportmap = new OpenLayers.Layer.OSM.TransportMap(i18n("javascripts.map.base.transport_map"), { + var transportmap = new OpenLayers.Layer.OSM.TransportMap(I18n.t("javascripts.map.base.transport_map"), { attribution: "Tiles courtesy of Andy Allan", keyid: "transportmap", displayOutsideMaxExtent: true, @@ -49,7 +49,7 @@ function createMap(divName, options) { }); map.addLayer(transportmap); - var mapquest = new OpenLayers.Layer.OSM(i18n("javascripts.map.base.mapquest"), [ + var mapquest = new OpenLayers.Layer.OSM(I18n.t("javascripts.map.base.mapquest"), [ "http://otile1.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png", "http://otile2.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png", "http://otile3.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png", @@ -71,6 +71,16 @@ function createMap(divName, options) { }); map.addLayer(markers); + map.dataLayer = new OpenLayers.Layer(I18n.t('browse.start_rjs.data_layer_name'), { + visibility: false, + displayInLayerSwitcher: false + }); + map.addLayer(map.dataLayer); + + $("#" + divName).on("resized", function () { + map.updateSize(); + }); + return map; } diff --git a/app/assets/javascripts/openlayers.js.erb b/app/assets/javascripts/openlayers.js.erb index ebb9578a3..66d991f82 100644 --- a/app/assets/javascripts/openlayers.js.erb +++ b/app/assets/javascripts/openlayers.js.erb @@ -35,3 +35,5 @@ OpenLayers.Util.origGetImageLocation = OpenLayers.Util.getImageLocation; OpenLayers.Util.getImageLocation = function(image) { return OpenLayers.Util.imageURLs[image] || OpenLayers.Util.origGetImageLocation(image); }; + +OpenLayers.Lang.setCode($('html').attr('lang')); diff --git a/app/assets/javascripts/params.js b/app/assets/javascripts/params.js new file mode 100644 index 000000000..5373625dc --- /dev/null +++ b/app/assets/javascripts/params.js @@ -0,0 +1,100 @@ +OSM.mapParams = function (search) { + var params = {}, mapParams = {}, loc; + + search = (search || window.location.search).replace('?', '').split('&'); + + for (var i = 0; i < search.length; ++i) { + var pair = search[i], + j = pair.indexOf('='), + key = pair.slice(0, j), + val = pair.slice(++j); + params[key] = decodeURIComponent(val); + } + + if (params.mlon && params.mlat) { + mapParams.marker = true; + mapParams.mlon = parseFloat(params.mlon); + mapParams.mlat = parseFloat(params.mlat); + } + + if (params.layers) { + mapParams.layers = params.layers; + } + + if (params.node || params.way || params.relation) { + mapParams.object = true; + mapParams.object_zoom = true; + + if (params.node) { + mapParams.object_type = 'node'; + mapParams.object_id = parseInt(params.node); + } else if (params.way) { + mapParams.object_type = 'way'; + mapParams.object_id = parseInt(params.way); + } else if (params.relation) { + mapParams.object_type = 'relation'; + mapParams.object_id = parseInt(params.relation); + } + } + + // Decide on a lat lon to initialise the map with. Various ways of doing this + if (params.bbox) { + var bbox = params.bbox.split(","); + mapParams.bbox = true; + mapParams.minlon = parseFloat(bbox[0]); + mapParams.minlat = parseFloat(bbox[1]); + mapParams.maxlon = parseFloat(bbox[2]); + mapParams.maxlat = parseFloat(bbox[3]); + mapParams.object_zoom = false; + } else if (params.minlon && params.minlat && params.maxlon && params.maxlat) { + mapParams.bbox = true; + mapParams.minlon = parseFloat(params.minlon); + mapParams.minlat = parseFloat(params.minlat); + mapParams.maxlon = parseFloat(params.maxlon); + mapParams.maxlat = parseFloat(params.maxlat); + 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.lat = parseFloat(loc[1]); + mapParams.zoom = parseInt(loc[2]); + mapParams.layers = loc[3]; + } else if (OSM.home) { + mapParams.lon = OSM.home.lon; + mapParams.lat = OSM.home.lat; + mapParams.zoom = 10; + } else if (OSM.location) { + mapParams.bbox = true; + mapParams.minlon = OSM.location.minlon; + mapParams.minlat = OSM.location.minlat; + mapParams.maxlon = OSM.location.maxlon; + mapParams.maxlat = OSM.location.maxlat; + } else { + mapParams.lon = -0.1; + mapParams.lat = 51.5; + mapParams.zoom = parseInt(params.zoom || 5); + } + + if (mapParams.bbox) { + mapParams.box = params.box == "yes"; + mapParams.lon = (mapParams.minlon + mapParams.maxlon) / 2; + mapParams.lat = (mapParams.minlat + mapParams.maxlat) / 2; + } + + var scale = parseFloat(params.scale); + if (scale > 0) { + mapParams.zoom = Math.log(360.0 / (scale * 512.0)) / Math.log(2.0); + } + + return mapParams; +}; diff --git a/app/assets/javascripts/piwik.js b/app/assets/javascripts/piwik.js new file mode 100644 index 000000000..d0443ae6d --- /dev/null +++ b/app/assets/javascripts/piwik.js @@ -0,0 +1,21 @@ +if (OSM.PIWIK_LOCATION && OSM.PIWIK_SITE) { + $(document).ready(function () { + var base = document.location.protocol + "//" + OSM.PIWIK_LOCATION + "/"; + + $.ajax({ + url: base + "piwik.js", + dataType: "script", + cache: true, + success: function () { + var piwikTracker = Piwik.getTracker(base + "piwik.php", OSM.PIWIK_SITE); + + piwikTracker.trackPageView(); + piwikTracker.enableLinkTracking(); + + $("meta[name=piwik-goal]").each(function () { + piwikTracker.trackGoal($(this).attr("content")); + }); + } + }); + }); +} diff --git a/app/assets/javascripts/resize.js b/app/assets/javascripts/resize.js new file mode 100644 index 000000000..64c006a0b --- /dev/null +++ b/app/assets/javascripts/resize.js @@ -0,0 +1,53 @@ +function resizeContent() { + var content = $("#content"); + var leftMargin = parseInt(content.css("left")); + var rightMargin = parseInt(content.css("right")); + var bottomMargin = parseInt(content.css("bottom")); + + if ($("html").attr("dir") == "ltr") { + content.width($(window).width() - content.prop("offsetLeft") - rightMargin); + } else { + content.width($(window).width() - content.prop("offsetRight") - leftMargin); + } + + content.height($(window).height() - content.prop("offsetTop") - bottomMargin); +} + +function resizeMap() { + var content_width = $("#content").width(); + var content_height = $("#content").height(); + var sidebar_width = 0; + var left_border = parseFloat($("#map").css("border-left-width")); + var right_border = parseFloat($("#map").css("border-right-width")); + var top_border = parseFloat($("#map").css("border-top-width")); + var bottom_border = parseFloat($("#map").css("border-bottom-width")); + + $("#sidebar:visible").each(function () { + sidebar_width = sidebar_width + $(this).outerWidth(true); + }); + + if ($("html").attr("dir") == "ltr") { + $("#map").css("left", (sidebar_width) + "px"); + } else { + $("#map").css("right", (sidebar_width) + "px"); + } + + $("#map").width(content_width - sidebar_width - left_border - right_border); + $("#map").height(content_height - top_border - bottom_border); + $("#map").trigger("resized"); +} + +function handleResize() { + var brokenContentSize = $("#content").prop("offsetWidth") == 0; + + if (brokenContentSize) { + resizeContent(); + } + + resizeMap(); +} + +$(document).ready(function () { + $("#sidebar").on("opened", resizeMap); + $("#sidebar").on("closed", resizeMap); +}); diff --git a/app/assets/javascripts/richtext.js b/app/assets/javascripts/richtext.js new file mode 100644 index 000000000..78a9d452f --- /dev/null +++ b/app/assets/javascripts/richtext.js @@ -0,0 +1,68 @@ +$(document).ready(function () { + /* Hide the preview panes */ + $(".richtext_preview").hide(); + + /* + * When the text in an edit pane is changed, clear the contents of + * the associated preview pne so that it will be regenerated when + * the user next switches to it. + */ + $(".richtext_content textarea").change(function () { + $(this).parents(".richtext_container").find(".richtext_preview").empty(); + }); + + /* Disable all the edit buttons */ + $(".richtext_doedit").prop("disabled", true); + + /* Enable the preview buttons */ + $(".richtext_dopreview").prop("disabled", false); + + /* + * Install a click handler to switch to edit mode when the + * edit button is pressed. + */ + $(".richtext_doedit").click(function (event) { + var editor = $(this).parents(".richtext_container").find("textarea"); + var preview = $(this).parents(".richtext_container").find(".richtext_preview"); + + preview.hide(); + editor.show(); + + $(this).siblings(".richtext_dopreview").prop("disabled", false); + $(this).prop("disabled", true); + + event.preventDefault(); + }); + + /* + * Install a click handler to switch to preview mode when the + * preview button is pressed. + */ + $(".richtext_dopreview").click(function (event) { + var editor = $(this).parents(".richtext_container").find("textarea"); + var preview = $(this).parents(".richtext_container").find(".richtext_preview"); + var width = editor.outerWidth() - preview.outerWidth() + preview.innerWidth(); + var minHeight = editor.outerHeight() - preview.outerHeight() + preview.innerHeight(); + + if (preview.contents().length == 0) { + preview.oneTime(500, "loading", function () { + preview.addClass("loading"); + }); + + preview.load(editor.data("previewUrl"), { text: editor.val() }, function () { + preview.stopTime("loading"); + preview.removeClass("loading"); + }); + } + + editor.hide(); + preview.width(width); + preview.css("min-height", minHeight + "px"); + preview.show(); + + $(this).siblings(".richtext_doedit").prop("disabled", false); + $(this).prop("disabled", true); + + event.preventDefault(); + }); +}); diff --git a/app/assets/javascripts/sidebar.js b/app/assets/javascripts/sidebar.js new file mode 100644 index 000000000..a5d906980 --- /dev/null +++ b/app/assets/javascripts/sidebar.js @@ -0,0 +1,24 @@ +function openSidebar(options) { + options = options || {}; + + $("#sidebar").trigger("closed"); + + if (options.title) { $("#sidebar_title").html(options.title); } + + if (options.width) { $("#sidebar").width(options.width); } + else { $("#sidebar").width("30%"); } + + $("#sidebar").css("display", "block"); + + $("#sidebar").trigger("opened"); +}; + +$(document).ready(function () { + $(".sidebar_close").click(function (e) { + $("#sidebar").css("display", "none"); + + $("#sidebar").trigger("closed"); + + e.preventDefault(); + }); +}); diff --git a/app/assets/stylesheets/common.css.scss b/app/assets/stylesheets/common.css.scss index f2f16ec85..c897e1184 100644 --- a/app/assets/stylesheets/common.css.scss +++ b/app/assets/stylesheets/common.css.scss @@ -64,6 +64,10 @@ h2 { margin: 25px 0 5px 0; } +#logo img { + border: 0px; +} + #logo h1 { font-size: 18px; line-height: 20px; @@ -83,6 +87,10 @@ h2 { display: none; } +#small-title img { + border: 0px; +} + /* Rules for the introductory text displayed in the left sidebar to new users */ .sidebar-copy { @@ -322,9 +330,16 @@ h2 { padding: 5px 10px; text-decoration: none; color: #333; + -webkit-transition: color 200ms ease-in; + -moz-transition: color 200ms ease-in; + -o-transition: color 200ms ease-in; + transition: color 200ms ease-in; } -#tabnav a:link.active, #tabnav a:visited.active { +body.site-index #tabnav a#viewanchor, +body.site-edit #tabnav a#editanchor, +body.changeset-list #tabnav a#historyanchor, +body.site-export #tabnav a#exportanchor { border-bottom: 1px solid #aaa; background: #9ed485; color: #000; @@ -383,6 +398,7 @@ h2 { #map { margin: 0px; + border: 0px; padding: 0px; } @@ -496,7 +512,10 @@ h2 { padding-right: 5px; } -#mapkey .mapkey-table-key { +#mapkey .mapkey-table-key img { + display: block; + margin-left: auto; + margin-right: auto; } #mapkey .mapkey-table-value { @@ -595,9 +614,9 @@ h2 { bottom: 0px; } -#content.site_index, -#content.site_edit, -#content.site_export { +.site-index #content, +.site-edit #content, +.site-export #content { border: 0px; padding: 0px; } @@ -635,7 +654,7 @@ h2 { /* Rules for the home page */ -.site_index #map { +.site-index #map { position: absolute; top: 0px; bottom: 0px; @@ -643,7 +662,7 @@ h2 { right: 0px; } -.site_export #map { +.site-export #map { position: absolute; top: 0px; bottom: 0px; @@ -653,12 +672,13 @@ h2 { /* Rules for the edit page */ -.site_edit #map { +.site-edit #map { position: absolute; top: 0px; bottom: 0px; left: 0px; right: 0px; + overflow: hidden; } /* Rules for the changeset list shown by the history tab etc */ @@ -941,14 +961,14 @@ p#contributorGuidance { /* Rules for the user view */ -.user_view .user_map { +.user-view .user_map { position: relative; width: 400px; height: 400px; border: 1px solid #ccc; } -.user_view .user_map p#no_home_location { +.user-view .user_map p#no_home_location { position: absolute; top: 0px; bottom: 0px; diff --git a/app/assets/stylesheets/ltr.css.scss b/app/assets/stylesheets/ltr.css.scss index aaa182b8f..eb72ff9d1 100644 --- a/app/assets/stylesheets/ltr.css.scss +++ b/app/assets/stylesheets/ltr.css.scss @@ -148,17 +148,21 @@ html body { /* Rules for the diary list */ -.diary_entry_list img.user_thumbnail { +.diary_entry-list img.user_image { + float: right; +} + +.diary_entry-list img.user_thumbnail { float: right; } /* Rules for the diary entry view */ -.diary_entry_view img.user_image { +.diary_entry-view img.user_image { float: right; } -.diary_entry_view img.user_thumbnail { +.diary_entry-view img.user_thumbnail { float: right; } @@ -180,11 +184,11 @@ form#termsForm input#agree { /* Rules for the user view */ -.user_view img.user_image { +.user-view img.user_image { float: right; } -.user_view .user_map { +.user-view .user_map { float: right; } diff --git a/app/assets/stylesheets/rtl.css.scss b/app/assets/stylesheets/rtl.css.scss index c4cb08521..8dd38834b 100644 --- a/app/assets/stylesheets/rtl.css.scss +++ b/app/assets/stylesheets/rtl.css.scss @@ -148,17 +148,21 @@ html body { /* Rules for the diary list */ -.diary_entry_list img.user_thumbnail { +.diary_entry-list img.user_image { + float: left; +} + +.diary_entry-list img.user_thumnbail { float: left; } /* Rules for the diary entry view */ -.diary_entry_view img.user_image { +.diary_entry-view img.user_image { float: left; } -.diary_entry_view img.user_thumbnail { +.diary_entry-view img.user_thumbnail { float: left; } @@ -180,11 +184,11 @@ form#termsForm input#agree { /* Rules for the user view */ -.user_view img.user_image { +.user-view img.user_image { float: left; } -.user_view .user_map { +.user-view .user_map { float: left; } diff --git a/app/assets/stylesheets/small.css.scss b/app/assets/stylesheets/small.css.scss index 66cc68655..daacb5a7f 100644 --- a/app/assets/stylesheets/small.css.scss +++ b/app/assets/stylesheets/small.css.scss @@ -107,7 +107,7 @@ h1 { border-right: 0px; } -#content.site_index { +.site-index #content { left: 0px; right: 0px; top: 38px; diff --git a/app/controllers/browse_controller.rb b/app/controllers/browse_controller.rb index 73f0940d8..2c22a9b83 100644 --- a/app/controllers/browse_controller.rb +++ b/app/controllers/browse_controller.rb @@ -1,5 +1,5 @@ class BrowseController < ApplicationController - layout 'site' + layout 'site', :except => [ :start ] before_filter :authorize_web before_filter :set_locale @@ -7,11 +7,6 @@ class BrowseController < ApplicationController around_filter :web_timeout, :except => [:start] def start - @max_features = case - when browser.ie? && browser.version.to_i < 8 then 100 - when browser.ie? && browser.version.to_i < 9 then 500 - else 2000 - end end def relation diff --git a/app/controllers/diary_entry_controller.rb b/app/controllers/diary_entry_controller.rb index 68d3a81ee..52ed87f56 100644 --- a/app/controllers/diary_entry_controller.rb +++ b/app/controllers/diary_entry_controller.rb @@ -37,6 +37,7 @@ class DiaryEntryController < ApplicationController default_lang = @user.preferences.where(:k => "diary.default_language").first lang_code = default_lang ? default_lang.v : @user.preferred_language @diary_entry = DiaryEntry.new(:language_code => lang_code) + set_map_location render :action => 'edit' end end @@ -47,11 +48,11 @@ class DiaryEntryController < ApplicationController if @user != @diary_entry.user redirect_to :controller => 'diary_entry', :action => 'view', :id => params[:id] - elsif params[:diary_entry] - if @diary_entry.update_attributes(params[:diary_entry]) - redirect_to :controller => 'diary_entry', :action => 'view', :id => params[:id] - end + elsif params[:diary_entry] and @diary_entry.update_attributes(params[:diary_entry]) + redirect_to :controller => 'diary_entry', :action => 'view', :id => params[:id] end + + set_map_location rescue ActiveRecord::RecordNotFound render :action => "no_such_entry", :status => :not_found end @@ -212,4 +213,22 @@ private def user_specific_list? params[:friends] or params[:nearby] end + + ## + # decide on a location for the diary entry map + def set_map_location + if @diary_entry.latitude and @diary_entry.longitude + @lon = @diary_entry.longitude + @lat = @diary_entry.latitude + @zoom = 12 + elsif @user.home_lat.nil? or @user.home_lon.nil? + @lon = params[:lon] || -0.1 + @lat = params[:lat] || 51.5 + @zoom = params[:zoom] || 4 + else + @lon = @user.home_lon + @lat = @user.home_lat + @zoom = 12 + end + end end diff --git a/app/controllers/geocoder_controller.rb b/app/controllers/geocoder_controller.rb index 2b03790aa..ced95dce6 100644 --- a/app/controllers/geocoder_controller.rb +++ b/app/controllers/geocoder_controller.rb @@ -132,84 +132,6 @@ class GeocoderController < ApplicationController render :action => "error" end - def search_osm_namefinder - # get query parameters - query = params[:query] - - # create result array - @results = Array.new - - # ask OSM namefinder - response = fetch_xml("http://gazetteer.openstreetmap.org/namefinder/search.xml?find=#{escape_query(query)}") - - # parse the response - response.elements.each("searchresults/named") do |named| - lat = named.attributes["lat"].to_s - lon = named.attributes["lon"].to_s - zoom = named.attributes["zoom"].to_s - place = named.elements["place/named"] || named.elements["nearestplaces/named"] - type = named.attributes["info"].to_s.capitalize - name = named.attributes["name"].to_s - description = named.elements["description"].to_s - - if name.empty? - prefix = "" - name = type - else - prefix = t "geocoder.search_osm_namefinder.prefix", :type => type - end - - if place - distance = format_distance(place.attributes["approxdistance"].to_i) - direction = format_direction(place.attributes["direction"].to_i) - placename = format_name(place.attributes["name"].to_s) - suffix = t "geocoder.search_osm_namefinder.suffix_place", :distance => distance, :direction => direction, :placename => placename - - if place.attributes["rank"].to_i <= 30 - parent = nil - parentrank = 0 - parentscore = 0 - - place.elements.each("nearestplaces/named") do |nearest| - nearestrank = nearest.attributes["rank"].to_i - nearestscore = nearestrank / nearest.attributes["distance"].to_f - - if nearestrank > 30 and - ( nearestscore > parentscore or - ( nearestscore == parentscore and nearestrank > parentrank ) ) - parent = nearest - parentrank = nearestrank - parentscore = nearestscore - end - end - - if parent - parentname = format_name(parent.attributes["name"].to_s) - - if place.attributes["info"].to_s == "suburb" - suffix = t "geocoder.search_osm_namefinder.suffix_suburb", :suffix => suffix, :parentname => parentname - else - parentdistance = format_distance(parent.attributes["approxdistance"].to_i) - parentdirection = format_direction(parent.attributes["direction"].to_i) - suffix = t "geocoder.search_osm_namefinder.suffix_parent", :suffix => suffix, :parentdistance => parentdistance, :parentdirection => parentdirection, :parentname => parentname - end - end - end - else - suffix = "" - end - - @results.push({:lat => lat, :lon => lon, :zoom => zoom, - :prefix => prefix, :name => name, :suffix => suffix, - :description => description}) - end - - render :action => "results" - rescue Exception => ex - @error = "Error contacting gazetteer.openstreetmap.org: #{ex.to_s}" - render :action => "error" - end - def search_osm_nominatim # get query parameters query = params[:query] @@ -299,42 +221,6 @@ class GeocoderController < ApplicationController @sources.push({ :name => "geonames" }) end - def description_osm_namefinder - # get query parameters - lat = params[:lat] - lon = params[:lon] - types = params[:types] - max = params[:max] - - # create result array - @results = Array.new - - # ask OSM namefinder - response = fetch_xml("http://gazetteer.openstreetmap.org/namefinder/search.xml?find=#{types}+near+#{lat},#{lon}&max=#{max}") - - # parse the response - response.elements.each("searchresults/named") do |named| - lat = named.attributes["lat"].to_s - lon = named.attributes["lon"].to_s - zoom = named.attributes["zoom"].to_s - place = named.elements["place/named"] || named.elements["nearestplaces/named"] - type = named.attributes["info"].to_s - name = named.attributes["name"].to_s - description = named.elements["description"].to_s - distance = format_distance(place.attributes["approxdistance"].to_i) - direction = format_direction((place.attributes["direction"].to_i - 180) % 360) - prefix = t "geocoder.description_osm_namefinder.prefix", :distance => distance, :direction => direction, :type => type - @results.push({:lat => lat, :lon => lon, :zoom => zoom, - :prefix => prefix.capitalize, :name => name, - :description => description}) - end - - render :action => "results" - rescue Exception => ex - @error = "Error contacting gazetteer.openstreetmap.org: #{ex.to_s}" - render :action => "error" - end - def description_osm_nominatim # get query parameters lat = params[:lat] @@ -344,7 +230,7 @@ class GeocoderController < ApplicationController # create result array @results = Array.new - # ask OSM namefinder + # ask nominatim response = fetch_xml("#{NOMINATIM_URL}reverse?lat=#{lat}&lon=#{lon}&zoom=#{zoom}&accept-language=#{request.user_preferred_languages.join(',')}") # parse the response diff --git a/app/controllers/message_controller.rb b/app/controllers/message_controller.rb index 94bee5d35..c6a269a06 100644 --- a/app/controllers/message_controller.rb +++ b/app/controllers/message_controller.rb @@ -38,6 +38,8 @@ class MessageController < ApplicationController message = Message.find(params[:message_id]) if message.to_user_id == @user.id then + message.update_attribute(:message_read, true) + @body = "On #{message.sent_on} #{message.sender.display_name} wrote:\n\n#{message.body.gsub(/^/, '> ')}" @title = @subject = "Re: #{message.title.sub(/^Re:\s*/, '')}" @this_user = User.find(message.from_user_id) diff --git a/app/controllers/site_controller.rb b/app/controllers/site_controller.rb index fa33deeee..015da9e22 100644 --- a/app/controllers/site_controller.rb +++ b/app/controllers/site_controller.rb @@ -6,8 +6,10 @@ class SiteController < ApplicationController before_filter :set_locale before_filter :require_user, :only => [:edit] - def export - render :action => 'index' + def index + unless STATUS == :database_readonly or STATUS == :database_offline + session[:location] ||= OSM::IPLocation(request.env['REMOTE_ADDR']) + end end def permalink @@ -37,48 +39,6 @@ class SiteController < ApplicationController if editor == "remote" render :action => :index - else - # Decide on a lat lon to initialise potlatch with. Various ways of doing this - if params['lon'] and params['lat'] - @lon = params['lon'].to_f - @lat = params['lat'].to_f - @zoom = params['zoom'].to_i - - elsif params['mlon'] and params['mlat'] - @lon = params['mlon'].to_f - @lat = params['mlat'].to_f - @zoom = params['zoom'].to_i - - elsif params['bbox'] - bbox = BoundingBox.from_bbox_params(params) - - @lon = bbox.centre_lon - @lat = bbox.centre_lat - @zoom = 16 - elsif params['minlon'] and params['minlat'] and params['maxlon'] and params['maxlat'] - bbox = BoundingBox.from_lon_lat_params(params) - - @lon = bbox.centre_lon - @lat = bbox.centre_lat - @zoom = 16 - - elsif params['gpx'] - @lon = Trace.find(params['gpx']).longitude - @lat = Trace.find(params['gpx']).latitude - - elsif cookies.key?("_osm_location") - @lon, @lat, @zoom, layers = cookies["_osm_location"].split("|") - - elsif @user and !@user.home_lon.nil? and !@user.home_lat.nil? - @lon = @user.home_lon - @lat = @user.home_lat - - else - #catch all. Do nothing. lat=nil, lon=nil - #Currently this results in potlatch starting up at 0,0 (Atlantic ocean). - end - - @zoom = '17' if @zoom.nil? end end diff --git a/app/controllers/user_controller.rb b/app/controllers/user_controller.rb index 620ab5090..bfb0ef83b 100644 --- a/app/controllers/user_controller.rb +++ b/app/controllers/user_controller.rb @@ -259,10 +259,6 @@ class UserController < ApplicationController else password_authentication(params[:username], params[:password]) end - elsif params[:notice] - flash.now[:notice] = t "user.login.notice_#{params[:notice]}" - elsif flash[:notice].nil? - flash.now[:notice] = t 'user.login.notice' end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index e6a1e58e6..fb422cc17 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -9,14 +9,6 @@ module ApplicationHelper end end - def html_escape_unicode(text) - chars = ActiveSupport::Multibyte::Unicode.u_unpack(text).map do |c| - c < 127 ? c.chr : "&##{c.to_s};" - end - - return chars.join("") - end - def rss_link_to(*args) return link_to(image_tag("RSS.gif", :size => "16x16", :border => 0), Hash[*args], { :class => "rsssmall" }); end @@ -25,17 +17,6 @@ module ApplicationHelper return link_to(image_tag("RSS.gif", :size => "16x16", :border => 0), Hash[*args], { :class => "rsssmall" }); end - def javascript_strings - js = "" - - js << "\n" - - return raw(js) - end - def style_rules css = "" @@ -118,21 +99,4 @@ module ApplicationHelper link_to h(object.author_name), link_options.merge({:controller => "user", :action => "view", :display_name => object.author_name}) end end - -private - - def javascript_strings_for_key(key) - js = "" - value = I18n.t(key, :locale => "en") - - if value.is_a?(String) - js << "i18n_strings['#{key}'] = '" << escape_javascript(t(key)) << "';\n" - else - value.each_key do |k| - js << javascript_strings_for_key("#{key}.#{k}") - end - end - - return js - end end diff --git a/app/models/user.rb b/app/models/user.rb index e126adb98..889c40451 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -200,6 +200,7 @@ class User < ActiveRecord::Base self.image = nil self.email_valid = false self.new_email = nil + self.openid_url = nil self.status = "deleted" self.save end diff --git a/app/views/browse/_map.html.erb b/app/views/browse/_map.html.erb index d8ca30a15..44823218b 100644 --- a/app/views/browse/_map.html.erb +++ b/app/views/browse/_map.html.erb @@ -1,6 +1,3 @@ -<%= javascript_include_tag 'openlayers.js' %> -<%= javascript_include_tag 'map.js' %> - @@ -45,8 +42,6 @@ <% if map.instance_of? Changeset or (map.instance_of? Node and map.version > 1) or map.visible? %> <%= t 'layouts.project_name.title' %><%= ' | '+ @title if @title %> diff --git a/app/views/layouts/_piwik.html.erb b/app/views/layouts/_piwik.html.erb deleted file mode 100644 index 0ba307437..000000000 --- a/app/views/layouts/_piwik.html.erb +++ /dev/null @@ -1,14 +0,0 @@ - - diff --git a/app/views/layouts/site.html.erb b/app/views/layouts/site.html.erb index 0bff66656..064fbed0a 100644 --- a/app/views/layouts/site.html.erb +++ b/app/views/layouts/site.html.erb @@ -1,88 +1,92 @@ - + <%= render :partial => "layouts/head" %> - +
- <%= link_to(image_tag("osm_logo.png", :size => "16x16", :border => 0, :alt => t('layouts.logo.alt_text')), :controller => 'site', :action => 'index') %> + <%= link_to(image_tag("osm_logo.png", :size => "16x16", :alt => t('layouts.logo.alt_text')), root_path) %>

<%= t 'layouts.project_name.h1' %>

-
+
<%= render :partial => "layouts/flash", :locals => { :flash => flash } %> - <%= yield %>
-
<% if @user and @user.id %> - <%= raw(t 'layouts.welcome_user', :user_link => (link_to h(@user.display_name), {:controller => 'user', :action => 'view', :display_name => @user.display_name}, :title => t('layouts.welcome_user_link_tooltip'))) %> - <%= link_to t('layouts.welcome_user_link_tooltip'), {:controller => 'user', :action => 'view', :display_name => @user.display_name} %> | + <%= raw(t 'layouts.welcome_user', :user_link => (link_to h(@user.display_name), user_path(:display_name => @user.display_name), :title => t('layouts.welcome_user_link_tooltip'))) %> + <%= link_to t('layouts.welcome_user_link_tooltip'), user_path(:display_name => @user.display_name) %> | <%= yield :greeting %> <%= render :partial => "layouts/inbox" %> | - <%= link_to t('layouts.logout'), {:controller => 'user', :action => 'logout', :session => request.session_options[:id], :referer => request.fullpath}, {:id => 'logoutanchor', :title => t('layouts.logout_tooltip')}%> + <%= link_to t('layouts.logout'), logout_path(:session => request.session_options[:id], :referer => request.fullpath), {:id => 'logoutanchor', :title => t('layouts.logout_tooltip')}%> <% else %> - <%= link_to t('layouts.log_in'), {:controller => 'user', :action => 'login', :referer => request.fullpath}, {:id => 'loginanchor', :title => t('layouts.log_in_tooltip')} %> | - <%= link_to t('layouts.sign_up'), {:controller => 'user', :action => 'new'}, {:id => 'registeranchor', :title => t('layouts.sign_up_tooltip')} %> + <%= link_to t('layouts.log_in'), login_path(:referer => request.fullpath), {:id => 'loginanchor', :title => t('layouts.log_in_tooltip')} %> | + <%= link_to t('layouts.sign_up'), user_new_path, {:id => 'registeranchor', :title => t('layouts.sign_up_tooltip')} %> <% end %>
    - <% - viewclass = 'geolink llz layers' - editclass = 'geolink llz object minzoom13 disabled' - historyclass = 'geolink bbox minzoom11' - exportclass = 'geolink llz layers' - viewclass += ' active' if params['controller'] == 'site' and params['action'] == 'index' - editclass += ' active' if params['controller'] == 'site' and params['action'] == 'edit' - historyclass += ' active' if params['controller'] == 'changeset' and params['action'] == 'list' - exportclass += ' active' if params['controller'] == 'site' and params['action'] == 'export' - %> -
  • <%= link_to t('layouts.view'), {:controller => 'site', :action => 'index'}, {:id => 'viewanchor', :title => t('layouts.view_tooltip'), :class => viewclass} %>
  • -
  • <%= link_to h(t('layouts.edit')) + content_tag(:span, "▾", :class => "menuicon"), {:controller => 'site', :action => 'edit'}, {:id => 'editanchor', :title => t('javascripts.site.edit_tooltip'), :class => editclass} %>
  • -
  • <%= link_to t('layouts.history'), {:controller => 'changeset', :action => 'list' }, {:id => 'historyanchor', :title => t('javascripts.site.history_tooltip'), :class => historyclass} %>
  • -
  • <%= link_to t('layouts.export'), {:controller => 'site', :action => 'export'}, {:id => 'exportanchor', :title => t('layouts.export_tooltip'), :class => exportclass} %>
  • +
  • <%= link_to t('layouts.view'), root_path, { + :id => 'viewanchor', + :title => t('layouts.view_tooltip'), + :class => 'geolink llz layers' + } %>
  • +
  • <%= link_to h(t('layouts.edit')) + content_tag(:span, "▾", :class => "menuicon"), edit_path, { + :id => 'editanchor', + :title => t('javascripts.site.edit_tooltip'), + :data => { :minzoom => 13 }, + :class => 'geolink llz object disabled' + } %>
  • +
  • <%= link_to t('layouts.history'), browse_changesets_path, { + :id => 'historyanchor', + :data => { :minzoom => 11 }, + :title => t('javascripts.site.history_tooltip'), + :class => 'geolink bbox' + } %>
  • +
  • <%= link_to t('layouts.export'), export_path, { + :id => 'exportanchor', + :title => t('layouts.export_tooltip'), + :class => 'geolink llz layers' + } %>
- - -
- <%= yield :optionals %> - <% unless @user %> <% end %> - <% if STATUS == :database_offline or STATUS == :api_offline %> <% end %> - <% if false %> <% end %> -
  • <%= t'layouts.help' %> -
      -
    • <%= link_to(t('layouts.help_centre'), t('layouts.help_url'), :title => t('layouts.help_title')) %>
    • -
    • <%= link_to(t('layouts.documentation'), t('layouts.wiki_url'), :title => t('layouts.documentation_title')) %>
    • -
    • <%= link_to t('layouts.copyright'), {:controller => 'site', :action => 'copyright'} %>
    • -
    +
      +
    • <%= link_to(t('layouts.help_centre'), t('layouts.help_url'), :title => t('layouts.help_title')) %>
    • +
    • <%= link_to(t('layouts.documentation'), t('layouts.wiki_url'), :title => t('layouts.documentation_title')) %>
    • +
    • <%= link_to t('layouts.copyright'), copyright_path %>
    • +
  • <%= t'layouts.community' %> - +
  • -
  • <%= link_to t('layouts.gps_traces'), {:controller => 'trace', :action => 'list', :display_name => nil, :tag => nil, :page => nil}, {:id => 'traceanchor', :title => t('layouts.gps_traces_tooltip') } %>
  • +
  • <%= link_to t('layouts.gps_traces'), traces_path, { + :id => 'traceanchor', + :title => t('layouts.gps_traces_tooltip') + } %>
  • <%= yield :left_menu %>
-
- <%= link_to image_tag("sotm.png", :alt => t('layouts.sotm2012'), :title => t('layouts.sotm2012'), :border => "0"), "http://stateofthemap.org/register-now/" %> + <%= link_to image_tag("sotmpdx.png", + :alt => t('layouts.sotm2012'), + :title => t('layouts.sotm2012'), + :border => "0"), "http://stateofthemap.us/" %>
-
- - - <% if defined?(PIWIK_LOCATION) and defined?(PIWIK_SITE) -%> - <%= render :partial => "layouts/piwik" %> + <% end -%> diff --git a/app/views/site/_key.html.erb b/app/views/site/_key.html.erb index 15f64275c..19b08de4a 100644 --- a/app/views/site/_key.html.erb +++ b/app/views/site/_key.html.erb @@ -1,31 +1,3 @@ - - <% content_for :left_menu do %> -
  • <%= link_to t("site.key.map_key"), "#", :id => "open_map_key", :title => t("site.key.map_key_tooltip") %>
  • +
  • <%= link_to t("site.key.map_key"), {:action => :key}, :id => "open_map_key", :title => t("site.key.map_key_tooltip") %>
  • <% end %> diff --git a/app/views/site/_potlatch.html.erb b/app/views/site/_potlatch.html.erb index 2cdccc4b0..8180cee02 100644 --- a/app/views/site/_potlatch.html.erb +++ b/app/views/site/_potlatch.html.erb @@ -42,7 +42,8 @@ // 700,600 for fixed size, 100%,100% for resizable } - doSWF(<%= @lat || 'null' %>,<%= @lon || 'null' %>,<%= @zoom %>); + var params = OSM.mapParams(); + doSWF(params.lat, params.lon, params.zoom || 17); $(document).ready(function () { $("body").on("click", "a.set_position", function () { diff --git a/app/views/site/_potlatch2.html.erb b/app/views/site/_potlatch2.html.erb index 4559282ca..31e15f09d 100644 --- a/app/views/site/_potlatch2.html.erb +++ b/app/views/site/_potlatch2.html.erb @@ -69,8 +69,12 @@ <% elsif params[:way] -%> <% bbox = Way.find(params[:way]).bbox.to_unscaled -%> doSWF(<%= bbox.centre_lat %>,<%= bbox.centre_lon %>,16); + <% elsif params[:gpx] -%> + <% trace = Trace.find(params[:gpx]) -%> + doSWF(<%= trace.latitude %>,<%= trace.longitude %>,16); <% else -%> - doSWF(<%= @lat || 'null' %>,<%= @lon || 'null' %>,<%= @zoom %>); + var params = OSM.mapParams(); + doSWF(params.lat, params.lon, params.zoom || 17); <% end -%> $(document).ready(function () { diff --git a/app/views/site/_resize.html.erb b/app/views/site/_resize.html.erb deleted file mode 100644 index f26e2248c..000000000 --- a/app/views/site/_resize.html.erb +++ /dev/null @@ -1,51 +0,0 @@ - diff --git a/app/views/site/_sidebar.html.erb b/app/views/site/_sidebar.html.erb index 3b1b547b6..bea37d0d9 100644 --- a/app/views/site/_sidebar.html.erb +++ b/app/views/site/_sidebar.html.erb @@ -2,51 +2,9 @@ - +
    - - diff --git a/app/views/site/copyright.html.erb b/app/views/site/copyright.html.erb index 0ef9d7b2b..4a7a57bea 100644 --- a/app/views/site/copyright.html.erb +++ b/app/views/site/copyright.html.erb @@ -1,15 +1,3 @@ - - <% if @locale == 'en' %> <% if t('license_page.legal_babble', :locale => I18n.locale) != t('license_page.legal_babble', :locale => :en) %> @@ -45,6 +33,7 @@

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

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

    +

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

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

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

    @@ -53,20 +42,21 @@

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

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

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

    -

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

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

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

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

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

    + +

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

    +

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

    +

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

    diff --git a/app/views/site/edit.html.erb b/app/views/site/edit.html.erb index d68b989df..dadb9e4e5 100644 --- a/app/views/site/edit.html.erb +++ b/app/views/site/edit.html.erb @@ -15,9 +15,8 @@ <% end %> <% end %> -<%= render :partial => 'sidebar', :locals => { :onopen => "resizeMap();", :onclose => "resizeMap();" } %> +<%= render :partial => 'sidebar' %> <%= render :partial => 'search' %> -<%= render :partial => 'resize' %> <%= render :partial => preferred_editor %> @@ -27,11 +26,11 @@ $("#greeting").hide(); $("#tabnav").hide(); - $("#content").css("top", "10px"); + $("#content").css("top", "0px"); <% if t('html.dir') == "ltr" -%> - $("#content").css("left", "10px"); + $("#content").css("left", "0px"); <% else -%> - $("#content").css("right", "10px"); + $("#content").css("right", "0px"); <% end -%> handleResize(); @@ -42,11 +41,11 @@ $("#greeting").show(); $("#tabnav").show(); - $("#content").css("top", "35px"); + $("#content").css("top", "30px"); <% if t('html.dir') == "ltr" -%> - $("#content").css("left", "192px"); + $("#content").css("left", "185px"); <% else -%> - $("#content").css("right", "192px"); + $("#content").css("right", "185px"); <% end -%> handleResize(); diff --git a/app/views/site/index.html.erb b/app/views/site/index.html.erb index 4b37fc8af..58bc59c20 100644 --- a/app/views/site/index.html.erb +++ b/app/views/site/index.html.erb @@ -7,11 +7,11 @@ <% unless STATUS == :api_offline or STATUS == :database_offline -%> <% content_for :editmenu do -%>
  • <%= link_to t("browse.start_rjs.notes_layer_name"), "#", :id => "show_notes" %>
  • -
  • <%= link_to t("browse.start_rjs.data_layer_name"), "#", :id => "show_data" %>
  • +
  • <%= link_to t("browse.start_rjs.data_layer_name"), { :controller => :browse, :action => :start }, :id => "show_data" %>
  • <% end -%> <% end -%> -<%= render :partial => 'sidebar', :locals => { :onopen => "resizeMap();", :onclose => "resizeMap();" } %> +<%= render :partial => 'sidebar' %> <%= render :partial => 'key' %> <%= render :partial => 'search' %> @@ -40,104 +40,15 @@ <%= t'site.index.license.project_url' %> - <%= - t'site.index.license.notice', - :license_name => t('site.index.license.license_name'), - :project_name => t('site.index.license.project_name') - %> + <%= t'site.index.license.copyright' %> -<% -if params[:mlon] and params[:mlat] - marker = true - mlon = params[:mlon].to_f - mlat = params[:mlat].to_f -end - -if params[:node] or params[:way] or params[:relation] - object = true - object_zoom = true - - if params[:node] - object_type = 'node' - object_id = params[:node].to_i - elsif params[:way] - object_type = 'way' - object_id = params[:way].to_i - elsif params[:relation] - object_type = 'relation' - object_id = params[:relation].to_i - end -end - -# Decide on a lat lon to initialise the map with. Various ways of doing this -if params[:bbox] - bbox = true - minlon, minlat, maxlon, maxlat = params[:bbox].split(",").collect { |c| c.to_f } - layers = params[:layers] - box = true if params[:box] == "yes" - object_zoom = false -elsif params[:minlon] and params[:minlat] and params[:maxlon] and params[:maxlat] - bbox = true - minlon = params[:minlon].to_f - minlat = params[:minlat].to_f - maxlon = params[:maxlon].to_f - maxlat = params[:maxlat].to_f - layers = params[:layers] - box = true if params[:box]=="yes" - object_zoom = false -elsif params[:lon] and params[:lat] - lon = params[:lon].to_f - lat = params[:lat].to_f - zoom = params.fetch(:zoom, 5).to_i - layers = params[:layers] - object_zoom = false -elsif params[:mlon] and params[:mlat] - lon = params[:mlon].to_f - lat = params[:mlat].to_f - zoom = params.fetch(:zoom, 12).to_i - layers = params[:layers] - object_zoom = false -elsif cookies.key?("_osm_location") - lon,lat,zoom,layers = cookies["_osm_location"].split("|") -elsif @user and !@user.home_lon.nil? and !@user.home_lat.nil? - lon = @user.home_lon - lat = @user.home_lat - zoom = 10 -else - unless STATUS == :database_readonly or STATUS == :database_offline - session[:location] = OSM::IPLocation(request.env['REMOTE_ADDR']) unless session[:location] - end - - if session[:location] - bbox = true - minlon = session[:location][:minlon] - minlat = session[:location][:minlat] - maxlon = session[:location][:maxlon] - maxlat = session[:location][:maxlat] - else - lon = -0.1 - lat = 51.5 - zoom = params.fetch(:zoom, 5).to_i - end - - layers = params[:layers] -end -%> - -<%= javascript_include_tag 'openlayers.js' %> -<%= javascript_include_tag 'map.js' %> -<%= javascript_include_tag 'notes.js' %> - -<%= render :partial => 'resize' %> -