Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sometimes the script stops working (in Chrome or after the update) #200

Closed
deevroman opened this issue Feb 28, 2025 · 5 comments
Closed
Labels
bug Something isn't working

Comments

@deevroman
Copy link
Owner

deevroman commented Feb 28, 2025

For some reason, in my Chrome on macOS, the script sometimes does not show objects on the map. In Firefox, this occurs only after updating the script, and in this situation it is enough to reload the tab. And in Chrome, sometimes even restarting the browser doesn’t help.

Sometimes I notice that this happens when I’m logged out of OSM and logging in helps (wtf?). The map display also starts working if you just open the browser console. (WTF?)

The source of the problem is how the script gets the Leaflet map object. Now this is done with a dirty hack by adding a hook to Leaflet:

if ([prod_server.origin, dev_server.origin, local_server.origin].includes(location.origin)
&& !["/edit", "/id"].includes(location.pathname)) {
// This must be done as early as possible in order to pull the map object into the global scope
// https://github.com/deevroman/better-osm-org/issues/34
if (navigator.userAgent.includes("Firefox") && GM_info.scriptHandler === "Violentmonkey") {
function mapHook() {
console.log("start map intercepting")
window.wrappedJSObject.L.Map.addInitHook(exportFunction((function () {
if (this._container?.id === "map") {
window.wrappedJSObject.globalThis.map = this;
console.log("map intercepted");
}
}), window.wrappedJSObject)
)
}
window.wrappedJSObject.mapHook = exportFunction(mapHook, window.wrappedJSObject)
window.wrappedJSObject.mapHook()
if (window.wrappedJSObject.map instanceof HTMLElement) {
console.error("Please, reload page, if something doesn't work")
}
getMap = () => window.wrappedJSObject.map
getWindow = () => window.wrappedJSObject
} else {
function mapHook() {
console.log("start map intercepting")
unsafeWindow.L.Map.addInitHook(exportFunction((function () {
if (this._container?.id === "map") {
unsafeWindow.map = this;
console.log("map intercepted");
}
}), unsafeWindow)
)
}
unsafeWindow.mapHook = exportFunction(mapHook, unsafeWindow)
unsafeWindow.mapHook()
if (unsafeWindow.map instanceof HTMLElement) {
console.error("Please, reload page, if something doesn't work")
}
getMap = () => unsafeWindow.map
getWindow = () => unsafeWindow
}
map = getMap()

How can I try to solve the problem:

  • contact the openstreetmap-website maintainers so that the map variable is available in the global scope
  • try registering another hook that is called later and get to the map variable from its context
  • try reload the map so that the initialization hook works for sure
  • patch Leaflet sources at startup
@deevroman deevroman added the bug Something isn't working label Feb 28, 2025
@deevroman deevroman changed the title Sometimes the script stops working Sometimes the script stops working (in Chrome or after the update) Feb 28, 2025
@deevroman deevroman pinned this issue Feb 28, 2025
@deevroman
Copy link
Owner Author

deevroman commented Mar 1, 2025

https://erosman.github.io/firemonkey/src/content/help.html

@require
The API works slightly differently in comparison to other script managers as the target is not not stored. It uses fetch() to get the target the first time but on subsequently Request.cache will be used by the browser. Consequently, the latest version of the file will always be fetched. Please note that processing many scripts with many @require can take time when registering scripts (i.e. browser start-up, disabling & re-enabling Script/CSS and/or FireMonkey).

Similar prerequisites, interesting

@deevroman
Copy link
Owner Author

deevroman commented Mar 2, 2025

// ==UserScript==
// @name            Bug
// @version         1337
// @author       deevroman
// @match        https://www.openstreetmap.org/*
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_info
// @sandbox      JavaScript
// @run-at       document-start
// ==/UserScript==


const mapPositionsHistory = []
const mapPositionsNextHistory = []

function runPositionTracker() {
    setInterval(() => {
        if (!getMap()) return
        try {
            const m = getMap()
            const bound = [
                [m.getBounds().getSouth(), m.getBounds().getWest()],
                [m.getBounds().getNorth(), m.getBounds().getEast()]
            ]

            if (JSON.stringify(mapPositionsHistory[mapPositionsHistory.length - 1]) === JSON.stringify(bound)) {
                return;
            }
            // in case of a transition between positions
            // via timeout?
            if (JSON.stringify(mapPositionsNextHistory[mapPositionsNextHistory.length - 1]) === JSON.stringify(bound)) {
                return;
            }
            mapPositionsNextHistory.length = 0
            mapPositionsHistory.push(bound)
            if (mapPositionsHistory.length > 100) {
                mapPositionsHistory.shift()
                mapPositionsHistory.shift()
            }
        } catch {
            alert("Please, reload page")
        }
    }, 1000);
}


var map = null
var getMap = null
//var getWindow = null

function mapHook() {
    console.log("start map intercepting")
    console.log(unsafeWindow.L)
    unsafeWindow.L.Map.addInitHook(exportFunction((function () {
        if (this._container?.id === "map") {
            //unsafeWindow.map = this;
            console.log("map intercepted");
            alert("ok")
        }
    }), unsafeWindow)
                                  )
}

unsafeWindow.mapHook = exportFunction(mapHook, unsafeWindow)
unsafeWindow.mapHook()
if (unsafeWindow.map instanceof HTMLElement) {
    console.error("Please, reload page, if something doesn't work")
}
getMap = () => unsafeWindow.map
//getWindow = () => unsafeWindow
//map = getMap()

@deevroman
Copy link
Owner Author

First, launch without an open console.

@deevroman
Copy link
Owner Author

deevroman commented Mar 2, 2025

https://www.tampermonkey.net/documentation.php#meta:run_at

Defines the moment the script is injected. In opposition to other script handlers, @run-at defines the first possible moment a script wants to run. This means it may happen, that a script that uses the @require tag may be executed after the document is already loaded, cause fetching the required script took that long.

As expected, although it is not clear why everything starts working in an open console. I probably need to think about a workaround instead of trying to debug it.

deevroman added a commit that referenced this issue Mar 3, 2025
@deevroman
Copy link
Owner Author

deevroman commented Mar 3, 2025

Solved with a dirty hack. Add another hook for L.Layer and force osm.org show something on the map

deevroman added a commit that referenced this issue Mar 5, 2025
@deevroman deevroman unpinned this issue Mar 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant