6 August 2013 14:41

Mit Greasemonkey Scripts ändern

Seit heute Morgen aktualisiert OpenStreetMap die URL mit den Koordinaten in Echtzeit. Das ist ganz schön, da man zum Weitergeben der aktuellen Ansicht nur die URL kopieren muss.

Leider hat diese Technik auch einen Nachteil: Der Browserverlauf wird unnötig zugemüllt. Wenn man die Kartenansicht 50 Mal verändert, hat man auch 50 Einträge im Verlauf. Das können aber auch schnell hunderte werden und irgendwann werden alte Einträge zugunsten der OSM-Einträge gelöscht. Dass der Verlauf unübersichtlich wird, kommt noch hinzu.

Es musste eine Lösung her. Und wie modifiziert man fremde Webseiten lokal im Browser? Genau, mit Greasemonkey. Da gibt es nur ein kleines Problem: Man muss irgendwie an das L.Map-Objekt kommen, ggf. sogar noch tiefer in die Klassen eintauchen und sie modifizieren. Allerdings ist das Objekt nirgends global referenziert.

Wir drängeln uns vor

Da wir also nicht an das Objekt kommen, müssen wir den Code selbst verändern, bevor er ausgeführt wird. Dazu gibt es in Greasemonkey eine Option, die im Header des Userscripts angegeben wird:

// @run-at      document-start

Das sorgt dafür, dass das Script nicht erst nach allem anderen ausgeführt wird, sondern direkt am Anfang, wenn die Seite lädt. Zusätzlich setzen wir

// @grant       none

damit wir nicht erst aus der Greasemonkey-Sandbox "ausbrechen" müssen. Es ist also kein unsafeWindow oder ähnliches erforderlich.

Aber nicht ganz so schnell

Ziel ist es nun, die Funktion L.Hash.prototype.onMapMove, welche die URL ändert, durch eine andere Funktion zu ersetzen. Würden wir dies nun direkt im Userscript machen, würden wir eine Fehlermeldung bekommen, dass L unbekannt sei. Wir haben uns so weit vorgedrängelt, dass es einfach noch nicht geladen wurde.

Wir müssen also warten, bis das DOM geladen wurde, der JavaScript-Code aber noch nicht ausgeführt wurde. Dies erreichen wir mit einem Event-Listener, welcher auf das Event DOMContentLoaded reagiert. Somit ist der vollständige Code also:

document.addEventListener('DOMContentLoaded', function() { L.Hash.prototype.onMapMove = function() {}; }, false);

Das komplette Script gibt es hier auf userscripts.org.

Kommentare

Powered by BetaBlog
Login | RSS Beiträge RSS Kommentare Impressum