From 6af9589ea01fc26fc1c0d7007ebda4d19b6f36ac Mon Sep 17 00:00:00 2001 From: Marwin Hochfelsner <50826859+hlfan@users.noreply.github.com> Date: Fri, 1 May 2026 00:48:19 +0200 Subject: [PATCH] Move hash and title sync logic from iframe to parent --- app/assets/javascripts/application.js | 1 - app/assets/javascripts/edit/id.js.erb | 46 +++++++++++++++++++++++++++ app/assets/javascripts/id.js | 43 ++++++++----------------- 3 files changed, 59 insertions(+), 31 deletions(-) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 78abcb89d..f08184b87 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -1,6 +1,5 @@ //= require jquery3 //= require jquery_ujs -//= require jquery.throttle-debounce //= require js-cookie/dist/js.cookie //= require popper //= require bootstrap-sprockets diff --git a/app/assets/javascripts/edit/id.js.erb b/app/assets/javascripts/edit/id.js.erb index e7b3715df..07cc136ce 100644 --- a/app/assets/javascripts/edit/id.js.erb +++ b/app/assets/javascripts/edit/id.js.erb @@ -41,4 +41,50 @@ $(function () { location.reload(); } }); + + let hashChangedAutomatically = false; + window.addEventListener("message", function (event) { + if (event.source !== id[0].contentWindow || event.origin !== location.origin) return; + const msg = event.data; + switch (msg.type) { + case "hashchange": + return onIframeHashChange(msg.data); + case "titlechange": + return onIframeTitleChange(msg.data); + } + }); + + function onIframeHashChange(data) { + updateLinks(data, data.zoom); + + // Manually resolve URL to avoid iframe JS context weirdness. + // https://gist.github.com/jfirebaugh/5439412 + const hash = OSM.formatHash(data); + if (hash === location.hash) return; + + hashChangedAutomatically = true; + location.replace(location.href.replace(/(#.*|$)/, hash)); + } + + function onIframeTitleChange(title) { + document.title = [title, OSM.i18n.t("layouts.project_name.title")].filter(t => t).join(" | "); + } + + function postMessageToIframe(type, data) { + id[0].contentWindow.postMessage({ type, data }, location.origin); + } + + $("body").on("click", "a.set_position", function (e) { + e.preventDefault(); + postMessageToIframe("hashchange", $(this).data()); + }); + + addEventListener("hashchange", function (e) { + if (hashChangedAutomatically) { + hashChangedAutomatically = false; + return; + } + e.preventDefault(); + postMessageToIframe("hashchange", OSM.mapParams()); + }); }); diff --git a/app/assets/javascripts/id.js b/app/assets/javascripts/id.js index 32e7bad02..fecb04fb0 100644 --- a/app/assets/javascripts/id.js +++ b/app/assets/javascripts/id.js @@ -1,4 +1,5 @@ //= require @openstreetmap/id/dist/iD.js +//= require jquery.throttle-debounce /* globals iD */ @@ -34,25 +35,24 @@ document.addEventListener("DOMContentLoaded", function () { return; } - let hashChangedAutomatically = false; - id.map().on("move.embed", parent.$.throttle(250, function () { + function postMessageToParent(type, data) { + parent.postMessage({ type, data }, location.origin); + } + + id.map().on("move.embed", window.Cowboy.throttle(250, function () { if (id.inIntro()) return; const zoom = ~~id.map().zoom(), center = id.map().center(), llz = { lon: center[0], lat: center[1], zoom: zoom }; - parent.updateLinks(llz, zoom); - - // Manually resolve URL to avoid iframe JS context weirdness. - // https://gist.github.com/jfirebaugh/5439412 - const hash = parent.OSM.formatHash(llz); - if (hash !== parent.location.hash) { - hashChangedAutomatically = true; - parent.location.replace(parent.location.href.replace(/(#.*|$)/, hash)); - } + postMessageToParent("hashchange", llz); })); - function goToLocation(data) { + window.addEventListener("message", function (event) { + if (event.source !== parent || event.origin !== location.origin) return; + const msg = event.data; + if (!msg || msg.type !== "hashchange") return; + const data = msg.data; // 0ms timeout to avoid iframe JS context weirdness. // https://gist.github.com/jfirebaugh/5439412 setTimeout(function () { @@ -60,27 +60,10 @@ 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(); - const data = parent.$(this).data(); - goToLocation(data); - }); - - parent.addEventListener("hashchange", function (e) { - if (hashChangedAutomatically) { - hashChangedAutomatically = false; - return; - } - e.preventDefault(); - const data = parent.OSM.mapParams(); - goToLocation(data); }); - const projectTitle = parent.document.title; new MutationObserver(() => - parent.document.title = [document.title, projectTitle].filter(t => t).join(" | ") + postMessageToParent("titlechange", document.title) ).observe(document.querySelector("title"), { childList: true, subtree: true, characterData: true }); } }); -- 2.39.5