您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Navigate through map history using Alt + arrow keys and mouse control
// ==UserScript== // @name WME Map Nav History // @name:de WME Karten-Navigations-Historie // @name:es WME Historial de Navegación del Mapa // @description Navigate through map history using Alt + arrow keys and mouse control // @description:de Ermöglicht die Navigation durch die Kartenhistorie mit Alt + Pfeiltasten und Maussteuerung // @description:es Permite navegar por el historial del mapa usando Alt + teclas de flecha y control del ratón // @namespace https://greasyfork.org/de/users/863740-horst-wittlich // @version 2025.05.17 // @author hiwi234 // @include https://www.waze.com/editor* // @include https://www.waze.com/*/editor* // @include https://beta.waze.com/* // @exclude https://www.waze.com/user/*editor/* // @exclude https://www.waze.com/*/user/*editor/* // @grant none // @license MIT // ==/UserScript== /* global W */ (function() { 'use strict'; let navigationHistory = []; let currentIndex = -1; let isInitialized = false; let currentLanguage = (navigator.language || navigator.userLanguage).substring(0, 2); const translations = { en: { scriptActive: "Script active", back: "Back", forward: "Forward", controls: "Controls", previousPosition: "Previous position", nextPosition: "Next position", backButton: "Back button", forwardButton: "Forward button", hints: "Hints", historyLimit: "History stores up to 100 positions", autoSave: "New positions are automatically saved when moving the map" }, de: { scriptActive: "Script aktiv", back: "Zurück", forward: "Vorwärts", controls: "Steuerung", previousPosition: "Vorherige Position", nextPosition: "Nächste Position", backButton: "Zurück-Button", forwardButton: "Vorwärts-Button", hints: "Hinweise", historyLimit: "Die Historie speichert bis zu 100 Positionen", autoSave: "Neue Positionen werden beim Verschieben der Karte automatisch gespeichert" }, es: { scriptActive: "Script activo", back: "Atrás", forward: "Adelante", controls: "Controles", previousPosition: "Posición anterior", nextPosition: "Siguiente posición", backButton: "Botón atrás", forwardButton: "Botón adelante", hints: "Consejos", historyLimit: "El historial almacena hasta 100 posiciones", autoSave: "Las nuevas posiciones se guardan automáticamente al mover el mapa" } }; const t = (key) => { return (translations[currentLanguage] && translations[currentLanguage][key]) || translations.en[key]; }; function saveCurrentPosition() { if (!isInitialized || !W.map) return; const center = W.map.getCenter(); const zoom = W.map.getZoom(); const lastEntry = navigationHistory[currentIndex]; if (lastEntry && lastEntry.lat === center.lat && lastEntry.lon === center.lon && lastEntry.zoom === zoom) { return; } navigationHistory = navigationHistory.slice(0, currentIndex + 1); navigationHistory.push({ lat: center.lat, lon: center.lon, zoom: zoom }); currentIndex++; if (navigationHistory.length > 100) { navigationHistory.shift(); currentIndex--; } updateNavigationButtons(); } function navigateToPosition(position) { if (!position || !isInitialized || !W.map) return; try { const lonlat = new OpenLayers.LonLat(position.lon, position.lat); W.map.setCenter(lonlat, position.zoom); } catch (error) { console.error('WME Map Nav History: Navigation error:', error); } } function handleKeyDown(e) { if (!isInitialized) return; if (e.altKey && e.keyCode === 37) { navigateBack(); e.preventDefault(); } else if (e.altKey && e.keyCode === 39) { navigateForward(); e.preventDefault(); } } function navigateBack() { if (currentIndex > 0) { currentIndex--; navigateToPosition(navigationHistory[currentIndex]); updateNavigationButtons(); } } function navigateForward() { if (currentIndex < navigationHistory.length - 1) { currentIndex++; navigateToPosition(navigationHistory[currentIndex]); updateNavigationButtons(); } } function updateNavigationButtons() { const backBtn = document.getElementById('nav-history-back'); const forwardBtn = document.getElementById('nav-history-forward'); if (backBtn) { backBtn.disabled = currentIndex <= 0; backBtn.style.opacity = currentIndex <= 0 ? '0.5' : '1'; } if (forwardBtn) { forwardBtn.disabled = currentIndex >= navigationHistory.length - 1; forwardBtn.style.opacity = currentIndex >= navigationHistory.length - 1 ? '0.5' : '1'; } } async function createSidebarTab() { try { const { tabLabel, tabPane } = W.userscripts.registerSidebarTab("wme-nav-history"); tabLabel.innerText = 'NAV'; tabLabel.title = '<h4>Map Navigation History</h4>'; await W.userscripts.waitForElementConnected(tabPane); const styleSheet = document.createElement("style"); styleSheet.textContent = ` .nav-history-button { padding: 8px 15px; cursor: pointer; background: #4a89dc; color: white; border: none; border-radius: 4px; font-weight: 600; transition: all 0.3s ease; box-shadow: 0 2px 4px rgba(0,0,0,0.1); min-width: 100px; display: flex; align-items: center; justify-content: center; gap: 5px; } .nav-history-button:hover { background: #5d9cec; box-shadow: 0 4px 8px rgba(0,0,0,0.15); transform: translateY(-1px); } .nav-history-button:active { transform: translateY(1px); box-shadow: 0 1px 2px rgba(0,0,0,0.1); } .nav-history-button:disabled { background: #b5b5b5; cursor: not-allowed; transform: none; box-shadow: none; } .nav-history-container { background: #f8f9fa; border-radius: 8px; padding: 20px; margin: 10px 0; box-shadow: 0 2px 6px rgba(0,0,0,0.05); } `; document.head.appendChild(styleSheet); tabPane.innerHTML = ` <div class="nav-history-container"> <p style="margin-top: 0; color: #2c3e50;"><h4>WME Map Nav History</h4></p> <p style="color: #4CAF50; display: flex; align-items: center; gap: 5px;"> <span style="font-size: 18px;">✓</span> ${t('scriptActive')} </p> <div style="display: flex; gap: 15px; margin: 20px 0;"> <button id="nav-history-back" class="nav-history-button"> <span style="font-size: 16px;">⬅️</span> ${t('back')} </button> <button id="nav-history-forward" class="nav-history-button"> ${t('forward')} <span style="font-size: 16px;">➡️</span> </button> </div> <hr style="border: none; height: 1px; background: #e1e4e8; margin: 15px 0;"> <div style="background: #fff; padding: 15px; border-radius: 6px; border: 1px solid #e1e4e8;"> <b style="margin-top: 0; color: #2c3e50;">${t('controls')}:</b> <ul style="padding-left: 20px; color: #4a5568;"> <li><strong>Alt + ←</strong> ${t('previousPosition')}</li> <li><strong>Alt + →</strong> ${t('nextPosition')}</li> </ul> <b style="margin-top: 15px; color: #2c3e50;">${t('hints')}:</b> <ul style="padding-left: 20px; color: #4a5568;"> <li>${t('historyLimit')}</li> <li>${t('autoSave')}</li> </ul> </div> </div> `; const backBtn = tabPane.querySelector('#nav-history-back'); const forwardBtn = tabPane.querySelector('#nav-history-forward'); backBtn.addEventListener('click', navigateBack); forwardBtn.addEventListener('click', navigateForward); updateNavigationButtons(); return true; } catch (error) { console.error('WME Map Nav History: Error creating sidebar tab:', error); return false; } } function initializeScript() { if (isInitialized) return; try { W.map.events.register('moveend', null, saveCurrentPosition); document.addEventListener('keydown', handleKeyDown); createSidebarTab(); isInitialized = true; saveCurrentPosition(); console.log('WME Map Nav History: Successfully initialized'); } catch (error) { console.error('WME Map Nav History: Initialization error:', error); isInitialized = false; } } if (W?.userscripts?.state.isInitialized) { initializeScript(); } else { document.addEventListener("wme-initialized", initializeScript, { once: true, }); } })();