Greasy Fork is available in English.
Auto-refreshes the map in search mode. Adds an on/off button for this script. Disables "no geocaches" popup.
当前为
// ==UserScript==
// @name Geocaching Map Auto-Refresh
// @namespace http://greasyfork.icu/users/754130
// @version 1.0
// @description Auto-refreshes the map in search mode. Adds an on/off button for this script. Disables "no geocaches" popup.
// @author Bl4ke
// @match *.geocaching.com/play/map*
// @grant none
// ==/UserScript==
(function() {
"use strict";
// Global Variables
// number increases every time the map shows a new area, meaning the map has been dragged or zoomed
var area_current = 0;
var observersActive = false;
var rf_bttn;
// variables for measuring time between refreshes
var startTime_refresh = new Date();
var endTime_refresh;
// when mouse down, map is dragged
var mouseIsDown = false;
window.addEventListener('mousedown', function() {
mouseIsDown = true;
});
window.addEventListener('mouseup', function() {
mouseIsDown = false;
});
// hide and press refresh button if available
function handle_refresh_bttn() {
rf_bttn = document.getElementById("clear-map-control");
if(rf_bttn != null) {
rf_bttn.style.zIndex = "-2";
// for each area the refresh method is called
refresh(area_current);
}
}
// recursive function; presses refresh_bttn if map hasn't moved for a while and map isn't beeing dragged
function refresh(area_temporary, startTime_area){
// at first call set startTime_area
if(startTime_area == undefined){
startTime_area = new Date();
}
let endTime_refresh = new Date();
//if map area hasn't moved
if(area_temporary == area_current) {
//console.log("[AR-Debug] " + (endTime_refresh-startTime_area) + " ms");
// if map isn't moved for a short time and isn't dragged, else try again later
if(endTime_refresh - startTime_area > 850 && !mouseIsDown) {
// check if enough time since last refresh has passed, else try again later
endTime_refresh = new Date();
let cooldown = 4000;
if(endTime_refresh - startTime_refresh > cooldown){
rf_bttn.click();
console.log("[AR-Debug] Map refreshed!");
startTime_refresh = new Date();
}
else{
//console.log("[AR-Debug] waiting for cooldown until next refresh);
window.setTimeout(refresh, 200, area_temporary, startTime_area);
}
}
else {
window.setTimeout(refresh, 200, area_temporary, startTime_area);
}
}
}
//closes "no geocaches found" pop-up and restarts obervers
function close_popup() {
let close_bttn = document.querySelector("button.modal-close-control");
close_bttn.click();
console.log("[AR] Popup closed!");
stopObservers();
setTimeout(startObservers, 7000);
}
// callback function for observer, executed when mutations are observed
function callback(mutationsList, observer) {
area_current += 1;
//console.log("[AR-Debug] Map moved.");
handle_refresh_bttn();
}
// callback function for pop-up observer, executed when mutations are observed
function callback_popup(mutationsList, observer_popup) {
//console.log("[AR-Debug] Observer_popup firing.");
if(document.querySelector("button.modal-close-control") != null){
close_popup();
}
}
// create observer instances linked to their callback functions
const observer = new MutationObserver(callback);
const observer_popup = new MutationObserver(callback_popup);
function startObservers() {
// selecting the node that will be observed for mutations
const targetNode = document.querySelector("a.map-cta");
const targetNode_popup = document.body;
// options for the observer (which mutations to observe)
const config = { attributes: true, childList: false, subtree: false };
const config_popup = {attributes: false, childList: true, subtree: false };
// start observing the target nodes for configured mutations
observer.observe(targetNode, config);
observer_popup.observe(targetNode_popup, config_popup);
observersActive = true;
console.log("[AR] Observers started");
// check for refresh possibility on start
handle_refresh_bttn();
}
function stopObservers() {
observer_popup.disconnect();
observer.disconnect();
observersActive = false;
console.log("[AR] Observers stopped.");
}
// disables the observers temporarily when settings are opened so that the popup trigger isn't activated
function settings_popup_exemption() {
document.querySelector("button[aria-label='Map settings']").addEventListener('click', function(){
console.log("[AR] Settings opened. Disabling observers temporarily.");
stopObservers();
setTimeout(startObservers, 1000);
});
}
function insertOnOffBttn() {
var menuItem = document.createElement("li");
menuItem.setAttribute("role", "menuitem");
document.querySelector("button[aria-label='Map settings']").parentElement.parentElement.prepend(menuItem);
let onOffBttn = document.createElement("button");
onOffBttn.setAttribute("aria-label", "Auto-refresh Switch");
onOffBttn.setAttribute("class", "map-control");
onOffBttn.innerHTML = "Auto-Refresh";
onOffBttn.style.cssText += "background-color: white";
onOffBttn.style.cssText += "font-size: 60%";
// on-off function
onOffBttn.addEventListener('click', function(){
if(observersActive) {
// deactivating
onOffBttn.style.cssText += "background-color: rgb(228, 228, 228)";
stopObservers();
}
else {
// activating
onOffBttn.style.cssText += "background-color: white";
startObservers();
}
});
menuItem.append(onOffBttn);
}
// wait until map is loaded
function waitUntilMapAvailable() {
let mapNode = document.querySelector("div.map-container");
if(mapNode == null) {
// the node doesn't exist yet, wait and try again
window.setTimeout(waitUntilMapAvailable, 300);
return;
}
// setup
startObservers();
settings_popup_exemption(); //sets up exemption
insertOnOffBttn();
}
waitUntilMapAvailable();
})();