//= require leaflet.zoom
//= require leaflet.locationfilter
//= require i18n
- //= require oauth
//= require matomo
//= require richtext
// Disable the button group and also the buttons to avoid
// inconsistent behaviour when zooming
- var editDisabled = zoom < 13;
+ const editDisabled = zoom < 13;
$("#edit_tab")
.tooltip({ placement: "bottom" })
.tooltip(editDisabled ? "enable" : "disable")
let moreItemWidth = 0;
function updateHeader() {
- var windowWidth = $(window).width();
+ const windowWidth = $(window).width();
if (windowWidth < breakpointWidth) {
$("body").addClass("small-nav");
//= require router
$(document).ready(function () {
- var map = new L.OSM.Map("map", {
+ const map = new L.OSM.Map("map", {
zoomControl: false,
layerControl: false,
contextmenu: true,
});
OSM.loadSidebarContent = function (path, callback) {
- var content_path = path;
+ let content_path = path;
map.setSidebarOverlaid(false);
});
};
- var params = OSM.mapParams();
+ const token = $("head").data("oauthToken");
+ if (token) OSM.oauth = { authorization: "Bearer " + token };
+
+ const params = OSM.mapParams();
map.attributionControl.setPrefix("");
}
});
- var sidebar = L.OSM.sidebar("#map-ui")
+ const sidebar = L.OSM.sidebar("#map-ui")
.addTo(map);
- var position = $("html").attr("dir") === "rtl" ? "topleft" : "topright";
+ const position = $("html").attr("dir") === "rtl" ? "topleft" : "topright";
function addControlGroup(controls) {
for (const control of controls) control.addTo(map);
- var firstContainer = controls[0].getContainer();
+ const firstContainer = controls[0].getContainer();
$(firstContainer).find(".control-button").first()
.addClass("control-button-first");
- var lastContainer = controls[controls.length - 1].getContainer();
+ const lastContainer = controls[controls.length - 1].getContainer();
$(lastContainer).find(".control-button").last()
.addClass("control-button-last");
}
$(".leaflet-control .control-button").tooltip({ placement: "left", container: "body" });
- var expiry = new Date();
+ const expiry = new Date();
expiry.setYear(expiry.getFullYear() + 10);
map.on("moveend baselayerchange overlayadd overlayremove", function () {
Cookies.set("_osm_welcome", "hide", { secure: true, expires: expiry, path: "/", samesite: "lax" });
});
- var bannerExpiry = new Date();
+ const bannerExpiry = new Date();
bannerExpiry.setYear(bannerExpiry.getFullYear() + 1);
$("#banner .btn-close").on("click", function (e) {
- var cookieId = e.target.id;
+ const cookieId = e.target.id;
$("#banner").hide();
e.preventDefault();
if (cookieId) {
if (OSM.MATOMO) {
map.on("baselayerchange overlayadd", function (e) {
if (e.layer.options) {
- var goal = OSM.MATOMO.goals[e.layer.options.layerId];
+ const goal = OSM.MATOMO.goals[e.layer.options.layerId];
if (goal) {
$("body").trigger("matomogoal", goal);
}
function remoteEditHandler(bbox, object) {
- var remoteEditHost = "http://127.0.0.1:8111",
- osmHost = location.protocol + "//" + location.host,
- query = new URLSearchParams({
- left: bbox.getWest() - 0.0001,
- top: bbox.getNorth() + 0.0001,
- right: bbox.getEast() + 0.0001,
- bottom: bbox.getSouth() - 0.0001
- });
+ const remoteEditHost = "http://127.0.0.1:8111",
+ osmHost = location.protocol + "//" + location.host,
+ query = new URLSearchParams({
+ left: bbox.getWest() - 0.0001,
+ top: bbox.getNorth() + 0.0001,
+ right: bbox.getEast() + 0.0001,
+ bottom: bbox.getSouth() - 0.0001
+ });
if (object && object.type !== "note") query.set("select", object.type + object.id); // can't select notes
sendRemoteEditCommand(remoteEditHost + "/load_and_zoom?" + query, function () {
}
$("a[data-editor=remote]").click(function (e) {
- var params = OSM.mapParams(this.search);
+ const params = OSM.mapParams(this.search);
remoteEditHandler(map.getBounds(), params.object);
e.preventDefault();
});
}
OSM.Index = function (map) {
- var page = {};
+ const page = {};
page.pushstate = page.popstate = function () {
map.setSidebarOverlaid(true);
};
OSM.Browse = function (map, type) {
- var page = {};
+ const page = {};
- page.pushstate = page.popstate = function (path, id) {
+ page.pushstate = page.popstate = function (path, id, version) {
OSM.loadSidebarContent(path, function () {
- addObject(type, id);
+ addObject(type, id, version);
});
};
- page.load = function (path, id) {
- addObject(type, id, true);
+ page.load = function (path, id, version) {
+ addObject(type, id, version, true);
};
- function addObject(type, id, center) {
- var hashParams = OSM.parseHash(window.location.hash);
- map.addObject({ type: type, id: parseInt(id, 10) }, function (bounds) {
+ function addObject(type, id, version, center) {
+ const hashParams = OSM.parseHash(window.location.hash);
+ map.addObject({ type: type, id: parseInt(id, 10), version: version && parseInt(version, 10) }, function (bounds) {
if (!hashParams.center && bounds.isValid() &&
(center || !map.getBounds().contains(bounds))) {
OSM.router.withoutMoveListener(function () {
};
OSM.OldBrowse = function () {
- var page = {};
+ const page = {};
page.pushstate = page.popstate = function (path) {
OSM.loadSidebarContent(path);
return page;
};
- var history = OSM.History(map);
+ const history = OSM.History(map);
OSM.router = OSM.Router(map, {
"/": OSM.Index(map),
"/user/:display_name/history": history,
"/note/:id": OSM.Note(map),
"/node/:id(/history)": OSM.Browse(map, "node"),
- "/node/:id/history/:version": OSM.OldBrowse(),
+ "/node/:id/history/:version": OSM.Browse(map, "node"),
"/way/:id(/history)": OSM.Browse(map, "way"),
"/way/:id/history/:version": OSM.OldBrowse(),
"/relation/:id(/history)": OSM.Browse(map, "relation"),
OSM.Changeset = function (map) {
- var page = {},
- content = $("#sidebar_content");
+ const page = {},
+ content = $("#sidebar_content");
page.pushstate = page.popstate = function (path) {
OSM.loadSidebarContent(path, function () {
const changesetData = content.find("[data-changeset]").data("changeset");
changesetData.type = "changeset";
- var hashParams = OSM.parseHash(window.location.hash);
+ const hashParams = OSM.parseHash(window.location.hash);
initialize();
map.addObject(changesetData, function (bounds) {
if (!hashParams.center && bounds.isValid()) {
};
function updateChangeset(method, url, include_data) {
- let data;
+ const data = new URLSearchParams();
content.find("#comment-error").prop("hidden", true);
content.find("button[data-method][data-url]").prop("disabled", true);
if (include_data) {
- data = { text: content.find("textarea").val() };
- } else {
- data = {};
+ data.set("text", content.find("textarea").val());
}
- $.ajax({
- url: url,
- type: method,
- oauth: true,
- data: data,
- success: function () {
+ fetch(url, {
+ method: method,
+ headers: { ...OSM.oauth },
+ body: data
+ })
+ .then(response => {
+ if (response.ok) return response;
+ return response.text().then(text => {
+ throw new Error(text);
+ });
+ })
+ .then(() => {
OSM.loadSidebarContent(window.location.pathname, page.load);
- },
- error: function (xhr) {
+ })
+ .catch(error => {
content.find("button[data-method][data-url]").prop("disabled", false);
content.find("#comment-error")
- .text(xhr.responseText)
+ .text(error.message)
.prop("hidden", false)
.get(0).scrollIntoView({ block: "nearest" });
- }
- });
+ });
}
function initialize() {
content.find("button[data-method][data-url]").on("click", function (e) {
e.preventDefault();
- var data = $(e.target).data();
- var include_data = e.target.name === "comment";
+ const data = $(e.target).data();
+ const include_data = e.target.name === "comment";
updateChangeset(data.method, data.url, include_data);
});
OSM.NewNote = function (map) {
- var noteLayer = map.noteLayer,
- content = $("#sidebar_content"),
- page = {},
- addNoteButton = $(".control-note .control-button"),
- newNoteMarker,
+ const noteLayer = map.noteLayer,
+ content = $("#sidebar_content"),
+ page = {},
+ addNoteButton = $(".control-note .control-button");
+ let newNoteMarker,
halo;
- var noteIcons = {
+ const noteIcons = {
"new": L.icon({
iconUrl: OSM.NEW_NOTE_MARKER,
iconSize: [25, 40],
});
function createNote(location, text, callback) {
- $.ajax({
- url: "/api/0.6/notes.json",
- type: "POST",
- oauth: true,
- data: {
- fetch("/api/0.6/notes.json?", {
++ fetch("/api/0.6/notes.json", {
+ method: "POST",
+ headers: { ...OSM.oauth },
+ body: new URLSearchParams({
lat: location.lat,
lon: location.lng,
text
- },
- success: callback
- });
+ })
+ })
+ .then(response => response.json())
+ .then(callback);
}
function addCreatedNoteMarker(feature) {
- var marker = L.marker(feature.geometry.coordinates.reverse(), {
+ const marker = L.marker(feature.geometry.coordinates.reverse(), {
icon: noteIcons[feature.properties.status],
opacity: 0.9,
interactive: true
map.addLayer(noteLayer);
const params = new URLSearchParams(path.substring(path.indexOf("?")));
- var markerLatlng;
+ let markerLatlng;
if (params.has("lat") && params.has("lon")) {
markerLatlng = L.latLng(params.get("lat"), params.get("lon"));
createNote(location, text, (feature) => {
if (typeof OSM.user === "undefined") {
- var anonymousNotesCount = Number(Cookies.get("_osm_anonymous_notes_count")) || 0;
+ const anonymousNotesCount = Number(Cookies.get("_osm_anonymous_notes_count")) || 0;
Cookies.set("_osm_anonymous_notes_count", anonymousNotesCount + 1, { secure: true, expires: 30, path: "/", samesite: "lax" });
}
content.find("textarea").val("");
OSM.Note = function (map) {
- var content = $("#sidebar_content"),
- page = {};
+ const content = $("#sidebar_content"),
+ page = {};
- var noteIcons = {
+ const noteIcons = {
"new": L.icon({
iconUrl: OSM.NEW_NOTE_MARKER,
iconSize: [25, 40],
page.pushstate = page.popstate = function (path, id) {
OSM.loadSidebarContent(path, function () {
- initialize(path, id);
-
- var data = $(".details").data();
+ const data = $(".details").data();
if (!data) return;
- var latLng = L.latLng(data.coordinates.split(","));
- if (!map.getBounds().contains(latLng)) {
- OSM.router.withoutMoveListener(function () {
- map.setView(latLng, 15, { reset: true });
- });
- }
+ const latLng = L.latLng(data.coordinates.split(","));
+ initialize(path, id, map.getBounds().contains(latLng));
});
};
initialize(path, id);
};
- function initialize(path, id) {
+ function initialize(path, id, skipMoveToNote) {
content.find("button[name]").on("click", function (e) {
e.preventDefault();
- const data = $(e.target).data();
- const name = $(e.target).attr("name");
- const ajaxSettings = {
- url: data.url,
- type: data.method,
- oauth: true,
- success: () => {
+ const { url, method } = $(e.target).data(),
+ name = $(e.target).attr("name"),
+ data = new URLSearchParams();
+ content.find("button[name]").prop("disabled", true);
+
+ if (name !== "subscribe" && name !== "unsubscribe" && name !== "reopen") {
+ data.set("text", content.find("textarea").val());
+ }
+
+ fetch(url, {
+ method: method,
+ headers: { ...OSM.oauth },
+ body: data
+ })
+ .then(response => {
+ if (response.ok) return response;
+ return response.text().then(text => {
+ throw new Error(text);
+ });
+ })
+ .then(() => {
OSM.loadSidebarContent(path, () => {
- initialize(path, id);
+ initialize(path, id, false);
});
- },
- error: (xhr) => {
+ })
+ .catch(error => {
content.find("#comment-error")
- .text(xhr.responseText)
+ .text(error.message)
.prop("hidden", false)
.get(0).scrollIntoView({ block: "nearest" });
updateButtons();
- }
- };
-
- if (name !== "subscribe" && name !== "unsubscribe" && name !== "reopen") {
- ajaxSettings.data = { text: content.find("textarea").val() };
- }
-
- content.find("button[name]").prop("disabled", true);
- $.ajax(ajaxSettings);
+ });
});
content.find("textarea").on("input", function (e) {
content.find("textarea").val("").trigger("input");
- var data = $(".details").data();
+ const data = $(".details").data();
if (data) {
- var hashParams = OSM.parseHash(window.location.hash);
+ const hashParams = OSM.parseHash(window.location.hash);
map.addObject({
type: "note",
id: parseInt(id, 10),
latLng: L.latLng(data.coordinates.split(",")),
icon: noteIcons[data.status]
}, function () {
- if (!hashParams.center) {
- var latLng = L.latLng(data.coordinates.split(","));
+ if (!hashParams.center && !skipMoveToNote) {
+ const latLng = L.latLng(data.coordinates.split(","));
OSM.router.withoutMoveListener(function () {
map.setView(latLng, 15, { reset: true });
});
}
function updateButtons() {
- var resolveButton = content.find("button[name='close']");
- var commentButton = content.find("button[name='comment']");
+ const resolveButton = content.find("button[name='close']");
+ const commentButton = content.find("button[name='comment']");
content.find("button[name]").prop("disabled", false);
if (content.find("textarea").val() === "") {