autoprefixer-rails (10.4.19.0)
execjs (~> 2)
aws-eventstream (1.3.2)
- aws-partitions (1.1073.0)
- aws-sdk-core (3.221.0)
+ aws-partitions (1.1078.0)
+ aws-sdk-core (3.222.1)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
aws-sigv4 (~> 1.9)
aws-sdk-kms (1.99.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sigv4 (~> 1.5)
- aws-sdk-s3 (1.182.0)
+ aws-sdk-s3 (1.183.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
- logger (1.6.6)
+ logger (1.7.0)
logstasher (2.1.5)
activesupport (>= 5.2)
request_store
net-smtp (0.5.1)
net-protocol
nio4r (2.7.4)
- nokogiri (1.18.6)
+ nokogiri (1.18.7)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
oauth (1.1.0)
iniparse (~> 1.4)
rexml (>= 3.3.9)
parallel (1.26.3)
- parser (3.3.7.2)
+ parser (3.3.7.4)
ast (~> 2.4.1)
racc
pg (1.5.9)
rb-inotify (0.11.1)
ffi (~> 1.0)
rchardet (1.9.0)
- rdoc (6.13.0)
+ rdoc (6.13.1)
psych (>= 4.0.0)
regexp_parser (2.10.0)
reline (0.6.0)
rouge (4.5.1)
rtlcss (0.2.1)
mini_racer (>= 0.6.3)
- rubocop (1.74.0)
+ rubocop (1.75.1)
json (~> 2.3)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.1.0)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 2.9.3, < 3.0)
- rubocop-ast (>= 1.38.0, < 2.0)
+ rubocop-ast (>= 1.43.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.43.0)
rubocop-factory_bot (2.27.1)
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
- rubocop-minitest (0.37.1)
+ rubocop-minitest (0.38.0)
lint_roller (~> 1.1)
- rubocop (>= 1.72.1, < 2.0)
+ rubocop (>= 1.75.0, < 2.0)
rubocop-ast (>= 1.38.0, < 2.0)
- rubocop-performance (1.24.0)
+ rubocop-performance (1.25.0)
lint_roller (~> 1.1)
- rubocop (>= 1.72.1, < 2.0)
+ rubocop (>= 1.75.0, < 2.0)
rubocop-ast (>= 1.38.0, < 2.0)
- rubocop-rails (2.30.3)
+ rubocop-rails (2.31.0)
activesupport (>= 4.2.0)
lint_roller (~> 1.1)
rack (>= 1.1)
- rubocop (>= 1.72.1, < 2.0)
+ rubocop (>= 1.75.0, < 2.0)
rubocop-ast (>= 1.38.0, < 2.0)
rubocop-rake (0.7.1)
lint_roller (~> 1.1)
map.removeLayer(marker);
}
- marker = L.marker(e.latlng, { icon: OSM.getUserIcon() }).addTo(map)
+ marker = L.marker(e.latlng, { icon: OSM.getMarker({}) }).addTo(map)
.bindPopup(OSM.i18n.t("diary_entries.edit.marker_text"));
}
map.setView(centre, params.zoom);
if ($("#latitude").val() && $("#longitude").val()) {
- marker = L.marker(centre, { icon: OSM.getUserIcon() }).addTo(map)
+ marker = L.marker(centre, { icon: OSM.getMarker({}) }).addTo(map)
.bindPopup(OSM.i18n.t("diary_entries.edit.marker_text"));
}
const data = parent.OSM.mapParams();
goToLocation(data);
});
+
+ const projectTitle = parent.document.title;
+ new MutationObserver(() =>
+ parent.document.title = [document.title, projectTitle].filter(t => t).join(" | ")
+ ).observe(document.querySelector("title"), { childList: true, subtree: true, characterData: true });
}
});
-OSM.DirectionsEndpoint = function Endpoint(map, input, iconUrl, dragCallback, changeCallback) {
+OSM.DirectionsEndpoint = function Endpoint(map, input, marker, dragCallback, changeCallback) {
const endpoint = {};
endpoint.marker = L.marker([0, 0], {
- icon: L.icon({
- iconUrl: iconUrl,
- iconSize: [25, 41],
- iconAnchor: [12, 41],
- popupAnchor: [1, -34],
- shadowUrl: OSM.MARKER_SHADOW,
- shadowSize: [41, 41]
- }),
+ icon: OSM.getMarker(marker),
draggable: true,
autoPan: true
});
};
const endpoints = [
- OSM.DirectionsEndpoint(map, $("input[name='route_from']"), OSM.MARKER_GREEN, endpointDragCallback, endpointChangeCallback),
- OSM.DirectionsEndpoint(map, $("input[name='route_to']"), OSM.MARKER_RED, endpointDragCallback, endpointChangeCallback)
+ OSM.DirectionsEndpoint(map, $("input[name='route_from']"), { icon: "MARKER_GREEN" }, endpointDragCallback, endpointChangeCallback),
+ OSM.DirectionsEndpoint(map, $("input[name='route_to']"), { icon: "MARKER_RED" }, endpointDragCallback, endpointChangeCallback)
];
let downloadURL = null;
map.setView(OSM.home, 15, { reset: true });
});
marker = L.marker(OSM.home, {
- icon: OSM.getUserIcon(),
+ icon: OSM.getMarker({}),
title: OSM.i18n.t("javascripts.home.marker_title")
}).addTo(map);
} else {
const noteLayer = map.noteLayer;
let notes = {};
- const noteIcons = {
- "new": L.icon({
- iconUrl: OSM.NEW_NOTE_MARKER,
- iconSize: [25, 40],
- iconAnchor: [12, 40]
- }),
- "open": L.icon({
- iconUrl: OSM.OPEN_NOTE_MARKER,
- iconSize: [25, 40],
- iconAnchor: [12, 40]
- }),
- "closed": L.icon({
- iconUrl: OSM.CLOSED_NOTE_MARKER,
- iconSize: [25, 40],
- iconAnchor: [12, 40]
- })
- };
-
noteLayer.on("add", () => {
loadNotes();
map.on("moveend", loadNotes);
function updateMarker(old_marker, feature) {
let marker = old_marker;
if (marker) {
- marker.setIcon(noteIcons[feature.properties.status]);
+ marker.setIcon(OSM.getMarker({ icon: `${feature.properties.status}_NOTE_MARKER`, shadow: false, height: 40 }));
} else {
let title;
const description = feature.properties.comments[0];
}
marker = L.marker(feature.geometry.coordinates.reverse(), {
- icon: noteIcons[feature.properties.status],
+ icon: OSM.getMarker({ icon: `${feature.properties.status}_NOTE_MARKER`, shadow: false, height: 40 }),
title,
opacity: 0.8,
interactive: true
let newNoteMarker,
halo;
- const noteIcons = {
- "new": L.icon({
- iconUrl: OSM.NEW_NOTE_MARKER,
- iconSize: [25, 40],
- iconAnchor: [12, 40]
- }),
- "open": L.icon({
- iconUrl: OSM.OPEN_NOTE_MARKER,
- iconSize: [25, 40],
- iconAnchor: [12, 40]
- }),
- "closed": L.icon({
- iconUrl: OSM.CLOSED_NOTE_MARKER,
- iconSize: [25, 40],
- iconAnchor: [12, 40]
- })
- };
-
addNoteButton.on("click", function (e) {
e.preventDefault();
e.stopPropagation();
function addCreatedNoteMarker(feature) {
const marker = L.marker(feature.geometry.coordinates.reverse(), {
- icon: noteIcons[feature.properties.status],
+ icon: OSM.getMarker({ icon: `${feature.properties.status}_NOTE_MARKER`, shadow: false, height: 40 }),
opacity: 0.9,
interactive: true
});
if (newNoteMarker) map.removeLayer(newNoteMarker);
newNoteMarker = L.marker(latlng, {
- icon: noteIcons.new,
+ icon: OSM.getMarker({ icon: "NEW_NOTE_MARKER", shadow: false, height: 40 }),
opacity: 0.9,
draggable: true
});
const content = $("#sidebar_content"),
page = {};
- const noteIcons = {
- "new": L.icon({
- iconUrl: OSM.NEW_NOTE_MARKER,
- iconSize: [25, 40],
- iconAnchor: [12, 40]
- }),
- "open": L.icon({
- iconUrl: OSM.OPEN_NOTE_MARKER,
- iconSize: [25, 40],
- iconAnchor: [12, 40]
- }),
- "closed": L.icon({
- iconUrl: OSM.CLOSED_NOTE_MARKER,
- iconSize: [25, 40],
- iconAnchor: [12, 40]
- })
- };
-
page.pushstate = page.popstate = function (path, id) {
OSM.loadSidebarContent(path, function () {
const data = $(".details").data();
type: "note",
id: parseInt(id, 10),
latLng: L.latLng(data.coordinates.split(",")),
- icon: noteIcons[data.status]
+ icon: OSM.getMarker({ icon: `${data.status}_NOTE_MARKER`, shadow: false, height: 40 })
}, function () {
if (!hashParams.center && !skipMoveToNote) {
const latLng = L.latLng(data.coordinates.split(","));
if (!marker) {
const data = $(this).find("a.set_position").data();
- marker = L.marker([data.lat, data.lon], { icon: OSM.getUserIcon() });
+ marker = L.marker([data.lat, data.lon], { icon: OSM.getMarker({}) });
$(this).data("marker", marker);
}
return window.matchMedia("(prefers-color-scheme: dark)").matches;
};
-OSM.getUserIcon = function (url) {
- return L.icon({
- iconUrl: url || OSM.MARKER_RED,
- iconSize: [25, 41],
- iconAnchor: [12, 41],
- popupAnchor: [1, -34],
- shadowUrl: OSM.MARKER_SHADOW,
- shadowSize: [41, 41]
- });
+OSM.getMarker = function ({ icon = "MARKER_RED", shadow = true, height = 41 }) {
+ const options = {
+ iconUrl: OSM[icon.toUpperCase()] || OSM.MARKER_RED,
+ iconSize: [25, height],
+ iconAnchor: [12, height],
+ popupAnchor: [1, -34]
+ };
+ if (shadow) {
+ options.shadowUrl = OSM.MARKER_SHADOW;
+ options.shadowSize = [41, 41];
+ options.shadowAnchor = [12, 41];
+ }
+ return L.icon(options);
};
LAYER_DEFINITIONS: <%= MapLayers::full_definitions("config/layers.yml").to_json %>,
LAYERS_WITH_MAP_KEY: <%= YAML.load_file(Rails.root.join("config/key.yml")).keys.to_json %>,
+ MARKER_BLUE: <%= image_path("marker-blue.png").to_json %>,
MARKER_GREEN: <%= image_path("marker-green.png").to_json %>,
MARKER_RED: <%= image_path("marker-red.png").to_json %>,
if ($("#map").hasClass("set_location")) {
marker = L.marker([0, 0], {
- icon: OSM.getUserIcon(),
+ icon: OSM.getMarker({}),
keyboard: false,
interactive: false
});
$("[data-user]").each(function () {
const user = $(this).data("user");
if (user.lon && user.lat) {
- L.marker([user.lat, user.lon], { icon: OSM.getUserIcon(user.icon) }).addTo(map)
+ L.marker([user.lat, user.lon], { icon: OSM.getMarker({ icon: user.icon }) }).addTo(map)
.bindPopup(user.description, { minWidth: 200 });
}
});
<% user_data = {
:lon => contact.home_lon,
:lat => contact.home_lat,
- :icon => image_path(type == "following" ? "marker-blue.png" : "marker-green.png"),
+ :icon => type == "following" ? "MARKER_BLUE" : "MARKER_GREEN",
:description => render(:partial => "popup", :object => contact, :locals => { :type => type })
} %>
<%= tag.div :class => "clearfix row", :data => { :user => user_data } do %>
<% user_data = {
:lon => current_user.home_lon,
:lat => current_user.home_lat,
- :icon => image_path("marker-red.png"),
+ :icon => "MARKER_RED",
:description => render(:partial => "popup", :object => current_user, :locals => { :type => "your location" })
} %>
<%= tag.div "", :id => "map", :class => "content_map border border-secondary-subtle rounded z-0", :data => { :user => user_data } %>
<!--[if !IE || gte IE 9]><!-->
<%= javascript_include_tag "id" %>
<!-- <![endif]-->
+ <title></title>
</head>
<body>
<% data = {}
linkify_wiki_hosts: ["wiki.openstreetmap.org", "wiki.osm.org", "wiki.openstreetmap.com", "wiki.openstreetmaps.org", "osm.wiki", "www.osm.wiki", "wiki.osm.wiki"]
# Shorter host to replace wiki hosts
linkify_wiki_hosts_replacement: "osm.wiki"
+# Regexp for wiki prefix that can be removed
+linkify_wiki_optional_path_prefix: "^/wiki(?=/[A-Z])"
# External authentication credentials
#google_auth_id: ""
#google_auth_secret: ""
link_attr = 'rel="nofollow noopener noreferrer"'
Rinku.auto_link(ERB::Util.html_escape(text), mode, link_attr) do |url|
url = shorten_host(url, Settings.linkify_hosts, Settings.linkify_hosts_replacement)
- shorten_host(url, Settings.linkify_wiki_hosts, Settings.linkify_wiki_hosts_replacement)
+ shorten_host(url, Settings.linkify_wiki_hosts, Settings.linkify_wiki_hosts_replacement) do |path|
+ path.sub(Regexp.new(Settings.linkify_wiki_optional_path_prefix || ""), "")
+ end
end.html_safe
end
private
def shorten_host(url, hosts, hosts_replacement)
- %r{^https?://([^/]*)(.*)$}.match(url) do |m|
- "#{hosts_replacement}#{m[2]}" if hosts_replacement && hosts&.include?(m[1])
+ %r{^(https?://([^/]*))(.*)$}.match(url) do |m|
+ scheme_host, host, path = m.captures
+ if hosts&.include?(host)
+ path = yield(path) if block_given?
+ if hosts_replacement
+ "#{hosts_replacement}#{path}"
+ else
+ "#{scheme_host}#{path}"
+ end
+ end || url
end || url
end
end
end
end
- def test_text_to_html_linkify_wiki_replace
- with_settings(:linkify_wiki_hosts => ["replace-me-wiki.example.com"], :linkify_wiki_hosts_replacement => "wiki.example.com") do
+ def test_text_to_html_linkify_wiki_replace_prefix
+ with_settings(:linkify_wiki_hosts => ["replace-me-wiki.example.com"], :linkify_wiki_hosts_replacement => "wiki.example.com",
+ :linkify_wiki_optional_path_prefix => "^/wiki(?=/[A-Z])") do
+ r = RichText.new("text", "foo https://replace-me-wiki.example.com/wiki/Tag:surface%3Dmetal bar")
+ assert_html r do
+ assert_dom "a", :count => 1, :text => "wiki.example.com/Tag:surface%3Dmetal" do
+ assert_dom "> @href", "https://replace-me-wiki.example.com/wiki/Tag:surface%3Dmetal"
+ assert_dom "> @rel", "nofollow noopener noreferrer"
+ end
+ end
+ end
+ end
+
+ def test_text_to_html_linkify_wiki_replace_prefix_undefined
+ with_settings(:linkify_wiki_hosts => ["replace-me-wiki.example.com"], :linkify_wiki_hosts_replacement => "wiki.example.com",
+ :linkify_wiki_optional_path_prefix => nil) do
r = RichText.new("text", "foo https://replace-me-wiki.example.com/wiki/Tag:surface%3Dmetal bar")
assert_html r do
assert_dom "a", :count => 1, :text => "wiki.example.com/wiki/Tag:surface%3Dmetal" do
end
end
+ def test_text_to_html_linkify_wiki_replace_undefined_prefix
+ with_settings(:linkify_wiki_hosts => ["replace-me-wiki.example.com"], :linkify_wiki_hosts_replacement => nil,
+ :linkify_wiki_optional_path_prefix => "^/wiki(?=/[A-Z])") do
+ r = RichText.new("text", "foo https://replace-me-wiki.example.com/wiki/Tag:surface%3Dmetal bar")
+ assert_html r do
+ assert_dom "a", :count => 1, :text => "https://replace-me-wiki.example.com/Tag:surface%3Dmetal" do
+ assert_dom "> @href", "https://replace-me-wiki.example.com/wiki/Tag:surface%3Dmetal"
+ assert_dom "> @rel", "nofollow noopener noreferrer"
+ end
+ end
+ end
+ end
+
+ def test_text_to_html_linkify_wiki_replace_prefix_no_match
+ with_settings(:linkify_wiki_hosts => ["replace-me-wiki.example.com"], :linkify_wiki_hosts_replacement => "wiki.example.com",
+ :linkify_wiki_optional_path_prefix => "^/wiki(?=/[A-Z])") do
+ r = RichText.new("text", "foo https://replace-me-wiki.example.com/wiki/w bar")
+ assert_html r do
+ assert_dom "a", :count => 1, :text => "wiki.example.com/wiki/w" do
+ assert_dom "> @href", "https://replace-me-wiki.example.com/wiki/w"
+ assert_dom "> @rel", "nofollow noopener noreferrer"
+ end
+ end
+ end
+ end
+
def test_text_to_html_email
r = RichText.new("text", "foo example@example.com bar")
assert_html r do