autoprefixer-rails (10.4.16.0)
execjs (~> 2)
aws-eventstream (1.3.0)
- aws-partitions (1.954.0)
+ aws-partitions (1.956.0)
aws-sdk-core (3.201.1)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.651.0)
google-protobuf (3.25.3)
hashdiff (1.1.0)
hashie (5.0.0)
- highline (3.0.1)
+ highline (3.1.0)
+ reline
htmlentities (4.3.4)
http_accept_language (2.1.1)
i18n (1.14.5)
io-console (~> 0.5)
request_store (1.7.0)
rack (>= 1.4)
- rexml (3.3.1)
+ rexml (3.3.2)
strscan
rinku (2.0.6)
rotp (6.3.0)
rubocop (~> 1.41)
rubocop-factory_bot (2.26.1)
rubocop (~> 1.61)
- rubocop-minitest (0.35.0)
+ rubocop-minitest (0.35.1)
rubocop (>= 1.61, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0)
rubocop-performance (1.21.1)
// Add click handler to show OpenID field
$("#openid_open_url").click(function () {
- $("#openid_url").val("http://");
$("#login_auth_buttons").hide();
$("#openid_login_form").show();
});
page.pushstate = page.popstate = function (path) {
var params = Qs.parse(path.substring(path.indexOf("?") + 1));
- $(".search_form input[name=query]").val(params.query);
- $(".describe_location").hide();
+ if (params.query) {
+ $(".search_form input[name=query]").val(params.query);
+ $(".describe_location").hide();
+ } else if (params.lat && params.lon) {
+ $(".search_form input[name=query]").val(params.lat + ", " + params.lon);
+ $(".describe_location").hide();
+ }
OSM.loadSidebarContent(path, page.load);
};
$("<div>")
.appendTo($form)
.attr("class", "row mb-3")
+ .attr("id", "mapnik_scale_row")
.append($("<label>")
.attr("for", "mapnik_scale")
.attr("class", "col-auto col-form-label")
.attr("class", "form-check-input")
.bind("change", toggleFilter))));
- ["minlon", "minlat", "maxlon", "maxlat"].forEach(function (name) {
+ ["minlon", "minlat", "maxlon", "maxlat", "lat", "lon"].forEach(function (name) {
$("<input>")
.attr("id", "mapnik_" + name)
.attr("name", name)
});
$("<input>")
+ .attr("id", "map_format")
.attr("name", "format")
.attr("value", "mapnik")
.attr("type", "hidden")
.appendTo($form);
+ $("<input>")
+ .attr("id", "map_zoom")
+ .attr("name", "zoom")
+ .attr("value", map.getZoom())
+ .attr("type", "hidden")
+ .appendTo($form);
+
+ $("<input>")
+ .attr("id", "map_width")
+ .attr("name", "width")
+ .attr("value", 0)
+ .attr("type", "hidden")
+ .appendTo($form);
+
+ $("<input>")
+ .attr("id", "map_height")
+ .attr("name", "height")
+ .attr("value", 0)
+ .attr("type", "hidden")
+ .appendTo($form);
+
var csrf_param = $("meta[name=csrf-param]").attr("content"),
csrf_token = $("meta[name=csrf-token]").attr("content");
.appendTo($form);
var args = {
+ layer: "<span id=\"mapnik_image_layer\"></span>",
width: "<span id=\"mapnik_image_width\"></span>",
height: "<span id=\"mapnik_image_height\"></span>"
};
$("#mapnik_scale").val(scale);
}
- $("#mapnik_image_width").text(Math.round(size.x / scale / 0.00028));
- $("#mapnik_image_height").text(Math.round(size.y / scale / 0.00028));
+ const mapWidth = Math.round(size.x / scale / 0.00028);
+ const mapHeight = Math.round(size.y / scale / 0.00028);
+ $("#mapnik_image_width").text(mapWidth);
+ $("#mapnik_image_height").text(mapHeight);
+
+ const layer = map.getMapBaseLayerId();
+ const layerKeys = new Map([
+ ["mapnik", "standard"],
+ ["cyclemap", "cycle_map"],
+ ["transportmap", "transport_map"]
+ ]);
- if (map.getMapBaseLayerId() === "mapnik") {
+ $("#mapnik_image_layer").text(layerKeys.has(layer) ? I18n.t(`javascripts.map.base.${layerKeys.get(layer)}`) : "");
+ $("#map_format").val(layer);
+
+ $("#map_zoom").val(map.getZoom());
+ $("#mapnik_lon").val(map.getCenter().lng);
+ $("#mapnik_lat").val(map.getCenter().lat);
+ $("#map_width").val(mapWidth);
+ $("#map_height").val(mapHeight);
+
+ if (["cyclemap", "transportmap"].includes(map.getMapBaseLayerId())) {
+ $("#export-image").show();
+ $("#mapnik_scale_row").hide();
+ $("#export-warning").hide();
+ } else if (map.getMapBaseLayerId() === "mapnik") {
$("#export-image").show();
+ $("#mapnik_scale_row").show();
$("#export-warning").hide();
} else {
$("#export-image").hide();
# When the user clicks 'Export' we redirect to a URL which generates the export download
def finish
bbox = BoundingBox.from_lon_lat_params(params)
- format = params[:format]
+ style = params[:format]
+ format = params[:mapnik_format]
- case format
+ case style
when "osm"
# redirect to API map get
redirect_to :controller => "api/map", :action => "index", :bbox => bbox
when "mapnik"
# redirect to a special 'export' cgi script
- format = params[:mapnik_format]
scale = params[:mapnik_scale]
redirect_to "https://render.openstreetmap.org/cgi-bin/export?bbox=#{bbox}&scale=#{scale}&format=#{format}", :allow_other_host => true
+ when "cyclemap", "transportmap"
+ zoom = params[:zoom]
+ lat = params[:lat]
+ lon = params[:lon]
+ width = params[:width]
+ height = params[:height]
+
+ redirect_to "https://tile.thunderforest.com/static/#{style[..-4]}/#{lon},#{lat},#{zoom}/#{width}x#{height}.#{format}?apikey=#{Settings.thunderforest_key}", :allow_other_host => true
end
end
# External authentication support
- def auth_button(name, provider, options = {})
+ def auth_button(provider, options = {})
link_to(
- image_tag("#{name}.svg",
- :alt => t("application.auth_providers.#{name}.alt"),
+ image_tag("#{provider}.svg",
+ :alt => t("application.auth_providers.#{provider}.alt"),
:class => "rounded-1",
:size => "36"),
auth_path(options.merge(:provider => provider)),
:method => :post,
:class => "auth_button btn btn-light p-2",
- :title => t("application.auth_providers.#{name}.title")
+ :title => t("application.auth_providers.#{provider}.title")
)
end
- def auth_button_preferred(name, provider, options = {})
+ def auth_button_preferred(provider, options = {})
link_to(
- image_tag("#{name}.svg",
- :alt => t("application.auth_providers.#{name}.alt"),
+ image_tag("#{provider}.svg",
+ :alt => t("application.auth_providers.#{provider}.alt"),
:class => "rounded-1 me-3",
- :size => "36") + t("application.auth_providers.#{name}.title"),
+ :size => "36") + t("application.auth_providers.#{provider}.title"),
auth_path(options.merge(:provider => provider)),
:method => :post,
:class => "auth_button btn btn-outline-secondary border py-2 px-4 d-flex justify-content-center align-items-center",
- :title => t("application.auth_providers.#{name}.title")
+ :title => t("application.auth_providers.#{provider}.title")
)
end
<% if prefered_auth_button_available %>
<div class="col justify-content-center d-flex align-items-center flex-wrap">
- <% %w[google facebook microsoft github wikipedia].each do |provider| %>
- <% if Settings.key?("#{provider}_auth_id".to_sym) -%>
- <% if @preferred_auth_provider == provider %>
- <%= auth_button_preferred provider, provider %>
- <% end %>
- <% end -%>
- <% end -%>
+ <%= auth_button_preferred @preferred_auth_provider %>
</div>
<% end %>
<% %w[google facebook microsoft github wikipedia].each do |provider| %>
<% unless @preferred_auth_provider == provider %>
<% if Settings.key?("#{provider}_auth_id".to_sym) -%>
- <%= auth_button provider, provider %>
+ <%= auth_button provider %>
<% end -%>
<% end %>
<% end -%>
<%= t ".openid_url" %>
</label>
<%= hidden_field_tag("referer", params[:referer], :autocomplete => "off") %>
- <%= text_field_tag("openid_url", "", :tabindex => 20, :autocomplete => "on", :class => "form-control") %>
+ <%= text_field_tag("openid_url", "https://", :tabindex => 20, :autocomplete => "on", :class => "form-control") %>
<span class="form-text text-body-secondary">(<a href="<%= t "accounts.edit.openid.link" %>" target="_new"><%= t "accounts.edit.openid.link text" %></a>)</span>
</div>
<% if @entry.subscribers.exists?(current_user.id) %>
<%= link_to t(".unsubscribe"), diary_entry_unsubscribe_path(@entry.user, @entry), :method => :post, :class => "btn btn-sm btn-primary" %>
<% else %>
- <%= link_to t(".subscribe"), diary_entry_subscribe_path(@entry.user, @entry.id), :method => :post, :class => "btn btn-sm btn-primary" %>
+ <%= link_to t(".subscribe"), diary_entry_subscribe_path(@entry.user, @entry), :method => :post, :class => "btn btn-sm btn-primary" %>
<% end %>
</div>
<% end %>
link: https://openstreetmap.org.pl/2024/sotm-eu-2024-community-tickets-70/
img: banners/StateoftheMapEurope_2024.png
enddate: 2024-jul-18
-sotmasia_2023:
- id: sotmasia_2023
- alt: State of the Map Asia x Foss4G Thailand 2023
- link: https://stateofthemap.asia/
- img: banners/SOTMAsia_x_FOSS4G_2023.jpg
- startdate: 2023-oct-18
- enddate: 2023-nov-18
-sotmafrica_2023:
- id: sotmafrica_2023
- alt: State of the Map Africa 2023
- link: https://2023.stateofthemap.africa
- img: banners/StateOfTheMapAfrica_2023.jpg
+sotm_2024:
+ id: sotm_2024
+ alt: State of the Map 2024
+ link: https://2024.stateofthemap.org
+ img: banners/sotm_2024.png
srcset:
- - [banners/StateOfTheMapAfrica_2023.jpg, 1x]
- - [banners/StateOfTheMapAfrica_2023@2x.jpg, 2x]
- startdate: 2023-oct-30
- enddate: 2023-nov-30
+ - [banners/sotm_2024.png, 1x]
+ - [banners/sotm_2024@2x.png, 2x]
+ startdate: 2024-jul-10
+ enddate: 2024-sep-05
\ No newline at end of file
custom_dimensions: "Set custom dimensions"
format: "Format:"
scale: "Scale:"
- image_dimensions: "Image will show standard layer at %{width} x %{height}"
+ image_dimensions: "Image will show the %{layer} layer at %{width} x %{height}"
download: "Download"
short_url: "Short URL"
include_marker: "Include marker"
center_marker: "Center map on marker"
paste_html: "Paste HTML to embed in website"
view_larger_map: "View Larger Map"
- only_standard_layer: "Only the standard layer can be exported as an image"
+ only_standard_layer: "Only the Standard, Cycle Map and Transport layers can be exported as an image"
embed:
report_problem: "Report a problem"
key:
comment = create(:changeset_comment)
assert comment.visible
- post changeset_comment_hide_path(:id => comment)
+ post changeset_comment_hide_path(comment)
assert_response :unauthorized
assert comment.reload.visible
auth_header = basic_authorization_header create(:user).email, "test"
# not a moderator
- post changeset_comment_hide_path(:id => comment), :headers => auth_header
+ post changeset_comment_hide_path(comment), :headers => auth_header
assert_response :forbidden
assert comment.reload.visible
auth_header = basic_authorization_header create(:moderator_user).email, "test"
# bad comment id
- post changeset_comment_hide_path(:id => 999111), :headers => auth_header
+ post changeset_comment_hide_path(999111), :headers => auth_header
assert_response :not_found
assert comment.reload.visible
end
auth_header = basic_authorization_header create(:moderator_user).email, "test"
- post changeset_comment_hide_path(:id => comment), :headers => auth_header
+ post changeset_comment_hide_path(comment), :headers => auth_header
assert_response :success
assert_not comment.reload.visible
end
comment = create(:changeset_comment, :visible => false)
assert_not comment.visible
- post changeset_comment_unhide_path(:id => comment)
+ post changeset_comment_unhide_path(comment)
assert_response :unauthorized
assert_not comment.reload.visible
auth_header = basic_authorization_header create(:user).email, "test"
# not a moderator
- post changeset_comment_unhide_path(:id => comment), :headers => auth_header
+ post changeset_comment_unhide_path(comment), :headers => auth_header
assert_response :forbidden
assert_not comment.reload.visible
auth_header = basic_authorization_header create(:moderator_user).email, "test"
# bad comment id
- post changeset_comment_unhide_path(:id => 999111), :headers => auth_header
+ post changeset_comment_unhide_path(999111), :headers => auth_header
assert_response :not_found
assert_not comment.reload.visible
end
auth_header = basic_authorization_header create(:moderator_user).email, "test"
- post changeset_comment_unhide_path(:id => comment), :headers => auth_header
+ post changeset_comment_unhide_path(comment), :headers => auth_header
assert_response :success
assert comment.reload.visible
end
# bad changeset id
assert_no_difference "changeset.subscribers.count" do
- post api_changeset_subscribe_path(:id => 999111), :headers => auth_header
+ post api_changeset_subscribe_path(999111), :headers => auth_header
end
assert_response :not_found
get changeset_comments_feed_path(:id => changeset.id, :format => "rss")
assert_response :success
assert_equal "application/rss+xml", @response.media_type
- assert_select "rss", :count => 1 do
- assert_select "channel", :count => 1 do
- assert_select "item", :count => 3
- end
- end
- # Rails::Dom::Testing.html_document_fragment.parse(icons)
- # Gets comment Ids from HTML and checks that they are in descending order
-
last_comment_id = -1
assert_select "rss", :count => 1 do
- assert_select "description", :count => 3 do |descriptions|
- descriptions.children.each do |description|
- changeset_dom = Rails::Dom::Testing.html_document_fragment.parse(description.content)
- comment = changeset_dom.at_css(".changeset-comment-text")
- next unless comment
-
- id = comment.content.split[-1].to_i
- assert_operator id, "<", last_comment_id if last_comment_id != -1
- last_comment_id = id
+ assert_select "channel", :count => 1 do
+ assert_select "item", :count => 3 do |items|
+ items.each do |item|
+ assert_select item, "link", :count => 1 do |link|
+ match = assert_match(/^#{changeset_url changeset}#c(\d+)$/, link.text)
+ comment_id = match[1].to_i
+ assert_operator comment_id, "<", last_comment_id if last_comment_id != -1
+ last_comment_id = comment_id
+ end
+ end
end
end
end
assert_redirected_to "https://render.openstreetmap.org/cgi-bin/export?bbox=0.0,50.0,1.0,51.0&scale=12&format=test"
end
+ ###
+ # test the finish action for cyclemap images
+ def test_finish_cyclemap
+ post export_finish_path(:minlon => 0, :minlat => 50, :maxlon => 1, :maxlat => 51, :format => "cyclemap", :mapnik_scale => 12, :mapnik_format => "png", :zoom => 17, :lat => 1, :lon => 2, :width => 400, :height => 300)
+ assert_redirected_to "https://tile.thunderforest.com/static/cycle/2,1,17/400x300.png?apikey=#{Settings.thunderforest_key}"
+ end
+
+ ###
+ # test the finish action for transport images
+ def test_finish_transport
+ post export_finish_path(:minlon => 0, :minlat => 50, :maxlon => 1, :maxlat => 51, :format => "transportmap", :mapnik_scale => 12, :mapnik_format => "png", :zoom => 17, :lat => 1, :lon => 2, :width => 400, :height => 300)
+ assert_redirected_to "https://tile.thunderforest.com/static/transport/2,1,17/400x300.png?apikey=#{Settings.thunderforest_key}"
+ end
+
##
# test the embed action
def test_embed
end
def test_auth_button
- button = auth_button("google", "google")
+ button = auth_button("google")
img_tag = "<img alt=\"Google logo\" class=\"rounded-1\" src=\"/images/google.svg\" width=\"36\" height=\"36\" />"
assert_equal("<a class=\"auth_button btn btn-light p-2\" title=\"Log in with Google\" rel=\"nofollow\" data-method=\"post\" href=\"/auth/google\">#{img_tag}</a>", button)
end
--- /dev/null
+require "application_system_test_case"
+
+class SearchTest < ApplicationSystemTestCase
+ test "click on 'where is this' sets search input value" do
+ stub_request(:get, %r{^https://nominatim\.openstreetmap\.org/reverse\?})
+ .to_return(:status => 404)
+
+ visit "/#map=7/1.234/6.789"
+
+ assert_field "Search", :with => ""
+ click_on "Where is this?"
+ assert_field "Search", :with => "1.234, 6.789"
+ end
+end