From 1ba5b7fef0e468296f8d772aa4de02b681bdbf53 Mon Sep 17 00:00:00 2001 From: Martin Raifer Date: Wed, 11 Dec 2024 14:59:02 +0100 Subject: [PATCH] iD: listen to manual hashchanges from iframe parent Pan to the new `map` location when the hash change was not not triggered by map interaction from inside iD itself. This mirrors the behaviour when manually editing the `map` hash parameter on osm.org outside of iD. This also fixes https://github.com/openstreetmap/iD/issues/10592 (error in js console when iD is opened outside of an iframe by directly navigating to osm.org/id). --- app/assets/javascripts/id.js | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/id.js b/app/assets/javascripts/id.js index 706097bbaf..15f77b1c14 100644 --- a/app/assets/javascripts/id.js +++ b/app/assets/javascripts/id.js @@ -28,6 +28,12 @@ document.addEventListener("DOMContentLoaded", function () { .containerNode(container) .init(); + if (parent === window) { + // iD not opened in an iframe -> skip setting of parent handlers + return; + } + + var hashChangedAutomatically = false; id.map().on("move.embed", parent.$.throttle(250, function () { if (id.inIntro()) return; var zoom = ~~id.map().zoom(), @@ -40,14 +46,12 @@ document.addEventListener("DOMContentLoaded", function () { // https://gist.github.com/jfirebaugh/5439412 var hash = parent.OSM.formatHash(llz); if (hash !== parent.location.hash) { + hashChangedAutomatically = true; parent.location.replace(parent.location.href.replace(/(#.*|$)/, hash)); } })); - parent.$("body").on("click", "a.set_position", function (e) { - e.preventDefault(); - var data = parent.$(this).data(); - + function goToLocation(data) { // 0ms timeout to avoid iframe JS context weirdness. // https://gist.github.com/jfirebaugh/5439412 setTimeout(function () { @@ -55,6 +59,22 @@ document.addEventListener("DOMContentLoaded", function () { [data.lon, data.lat], Math.max(data.zoom || 15, 13)); }, 0); + } + + parent.$("body").on("click", "a.set_position", function (e) { + e.preventDefault(); + var data = parent.$(this).data(); + goToLocation(data); + }); + + parent.addEventListener("hashchange", function (e) { + if (hashChangedAutomatically) { + hashChangedAutomatically = false; + return; + } + e.preventDefault(); + var data = parent.OSM.mapParams(); + goToLocation(data); }); } });