WME Enhanced Actions

Enhance your editing experience by automating repetitive tasks, optimizing your workflow with keyboard shortcuts, and streamlining key actions. Designed to help Waze editors improve efficiency with customizable automation tools.

目前为 2024-09-10 提交的版本。查看 最新版本

// ==UserScript==
// @name         WME Enhanced Actions
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Enhance your editing experience by automating repetitive tasks, optimizing your workflow with keyboard shortcuts, and streamlining key actions. Designed to help Waze editors improve efficiency with customizable automation tools.
// @author       Astheron
// @match        https://www.waze.com/*
// @grant        none
// @license      MIT
// ==/UserScript==

/**
 * License and Credits:
 *
 * This script is licensed under the MIT License:
 * Copyright (c) 2024 Astheron
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this script and associated documentation files (the "Script"), to deal
 * in the Script without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Script, and to permit persons to whom the Script is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Script.
 *
 * THE SCRIPT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SCRIPT OR THE USE OR OTHER DEALINGS IN THE
 * SCRIPT.
 *
 * **Contact:** For more details or inquiries, you can contact the author, Astheron, on the Waze forum.
 */

(function() {
    'use strict';

    let autoSaveEnabled = JSON.parse(localStorage.getItem('autoSaveEnabled')) || false;
    let saveKeyCombination = JSON.parse(localStorage.getItem('saveKeyCombination')) || [];
    let addressPanelKeyCombination = JSON.parse(localStorage.getItem('addressPanelKeyCombination')) || [];

    function getEditorLanguage() {
        const url = window.location.href;
        if (url.includes('/es/')) {
            return 'es';
        }
        return 'en';
    }

    const lang = getEditorLanguage();
    const isSpanish = lang === 'es';

    const translations = {
        en: {
            title: 'WME Enhanced Actions',
            description: 'Automate editing tasks with customizable auto-save and key combinations.',
            setSaveKey: 'Set Save Key (or combination):',
            saveHint: 'Use combinations of Ctrl, Alt, Shift with other keys.',
            setAddressPanelKey: 'Set Address Panel Key (or combination):',
            addressHint: 'Use combinations of Ctrl, Alt, Shift with other keys to open the address panel.',
            by: 'Script developed by',
            moreInfo: 'For more information, visit the Waze forum.',
        },
        es: {
            title: 'WME Enhanced Actions',
            description: 'Automatiza las tareas de edición con funciones de guardado automático y combinaciones de teclas personalizables.',
            setSaveKey: 'Configurar tecla de guardado (o combinación):',
            saveHint: 'Usa combinaciones de Ctrl, Alt, Shift con otras teclas.',
            setAddressPanelKey: 'Configurar tecla para el panel de direcciones (o combinación):',
            addressHint: 'Usa combinaciones de Ctrl, Alt, Shift con otras teclas para abrir el panel de direcciones.',
            by: 'Script programado por',
            moreInfo: 'Para más información, visita el foro de Waze.',
        }
    };

    const t = isSpanish ? translations.es : translations.en;

    function initializeSidebarTab() {
        const { tabLabel, tabPane } = W.userscripts.registerSidebarTab("enhanced-actions");

        tabLabel.innerText = t.title;
        tabLabel.title = 'Configure Auto Save and Key Combos';

        tabPane.innerHTML = `
    <div style="font-family: Arial, sans-serif; padding: 10px; border: 1px solid #ccc; border-radius: 8px; background: #fafafa;">
        <h2 style="color: #4CAF50; font-size: 1.5em; margin-bottom: 10px;">${t.title}</h2>
        <p style="font-size: 0.9em; color: #666;">
            ${isSpanish ? 'Facilita el trabajo de los editores con automatización de tareas repetitivas, atajos de teclado personalizables y más herramientas para optimizar la experiencia de edición en Waze.' : 'Helps editors streamline their work with task automation, customizable keyboard shortcuts, and additional tools to enhance the Waze editing experience.'}
        </p>
        <hr style="border: none; border-top: 1px solid #eee; margin: 15px 0;">

        <div style="margin-bottom: 15px;">
            <label for="saveKeyInput" style="font-weight: bold;">${t.setSaveKey}</label>
            <input type="text" id="saveKeyInput" readonly placeholder="Click to set keys"
                   style="width: 200px; padding: 5px; margin-left: 10px; border: 1px solid #ccc; border-radius: 4px;">
            <p style="font-size: 0.85em; color: #888; margin-left: 20px;">${t.saveHint}</p>
        </div>

        <div style="margin-bottom: 15px;">
            <label for="addressPanelKeyInput" style="font-weight: bold;">${t.setAddressPanelKey}</label>
            <input type="text" id="addressPanelKeyInput" readonly placeholder="Click to set keys"
                   style="width: 200px; padding: 5px; margin-left: 10px; border: 1px solid #ccc; border-radius: 4px;">
            <p style="font-size: 0.85em; color: #888; margin-left: 20px;">${t.addressHint}</p>
        </div>

        <hr style="border: none; border-top: 1px solid #eee; margin: 15px 0;">

        <p style="font-size: 0.85em; color: #666;">
            ${t.by} <a href="https://www.waze.com/es/user/editor/Astheron" target="_blank" style="color: #4CAF50; text-decoration: none;">Astheron</a>.
        </p>
        <p style="font-size: 0.85em; color: #666;">
            ${t.moreInfo} <a href="https://www.waze.com/forum/viewtopic.php?t=413593" target="_blank" style="color: #4CAF50; text-decoration: none;">Waze forum</a>.
        </p>
    </div>
`;

        const saveKeyInput = tabPane.querySelector('#saveKeyInput');
        const addressPanelKeyInput = tabPane.querySelector('#addressPanelKeyInput');

        saveKeyInput.value = saveKeyCombination.join('+');
        addressPanelKeyInput.value = addressPanelKeyCombination.join('+');

        saveKeyInput.addEventListener('focus', (event) => {
            saveKeyInput.value = '';
            startRecordingKeyCombination(saveKeyInput, 'save');
        });

        addressPanelKeyInput.addEventListener('focus', (event) => {
            addressPanelKeyInput.value = '';
            startRecordingKeyCombination(addressPanelKeyInput, 'addressPanel');
        });

        W.userscripts.waitForElementConnected(tabPane).then(() => {
            console.log("Enhanced Actions tab connected.");
        });
    }

    function startRecordingKeyCombination(inputField, type) {
        let combination = [];

        const keydownListener = (event) => {
            event.preventDefault();

            let key = event.key;
            if (event.ctrlKey && !combination.includes('Ctrl')) {
                combination.push('Ctrl');
            }
            if (event.altKey && !combination.includes('Alt')) {
                combination.push('Alt');
            }
            if (event.shiftKey && !combination.includes('Shift')) {
                combination.push('Shift');
            }
            if (!['Control', 'Shift', 'Alt', 'Meta'].includes(key)) {
                combination.push(key);
            }

            inputField.value = combination.join('+');
        };

        const keyupListener = () => {
            if (type === 'save') {
                saveKeyCombination = combination;
                localStorage.setItem('saveKeyCombination', JSON.stringify(saveKeyCombination));
                autoSaveEnabled = combination.length > 0;
                localStorage.setItem('autoSaveEnabled', JSON.stringify(autoSaveEnabled));
            } else if (type === 'addressPanel') {
                addressPanelKeyCombination = combination;
                localStorage.setItem('addressPanelKeyCombination', JSON.stringify(addressPanelKeyCombination));
            }
            document.removeEventListener('keydown', keydownListener);
            document.removeEventListener('keyup', keyupListener);
        };

        document.addEventListener('keydown', keydownListener);
        document.addEventListener('keyup', keyupListener);
    }

    function blurActiveInput() {
        const activeElement = document.activeElement;
        if (activeElement && (activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA')) {
            activeElement.blur();
        }
    }

    function handleEnterPress(event) {
        if (event.key === 'Enter' &&
            !(document.activeElement.tagName === 'INPUT' || document.activeElement.tagName === 'TEXTAREA')) {
            event.preventDefault();

            blurActiveInput();

            let applyButton = document.querySelector('wz-button.save-button');
            if (applyButton) {
                setTimeout(() => {
                    applyButton.click();
                }, 100);
            } else {
                console.log("Apply button not found.");
            }
        }
    }

    function handleSaveKeyPress(event) {
        if (document.activeElement.tagName === 'INPUT' ||
            document.activeElement.tagName === 'TEXTAREA' ||
            document.activeElement.isContentEditable) {
            return;
        }

        const pressedCombination = [];

        if (event.ctrlKey) pressedCombination.push('Ctrl');
        if (event.altKey) pressedCombination.push('Alt');
        if (event.shiftKey) pressedCombination.push('Shift');
        if (!['Control', 'Shift', 'Alt', 'Meta'].includes(event.key)) {
            pressedCombination.push(event.key);
        }

        if (JSON.stringify(pressedCombination) === JSON.stringify(saveKeyCombination) && autoSaveEnabled) {
            event.preventDefault();

            blurActiveInput();

            let saveButton = document.querySelector('wz-button#save-button');
            if (saveButton && saveButton.getAttribute('disabled') === "false") {
                setTimeout(() => {
                    saveButton.click();
                }, 100);
            } else {
                console.log("Save button not found or disabled.");
            }
        }
    }

    function handleAddressPanelKeyPress(event) {
        if (document.activeElement.tagName === 'INPUT' ||
            document.activeElement.tagName === 'TEXTAREA' ||
            document.activeElement.isContentEditable) {
            return;
        }

        const pressedCombination = [];

        if (event.ctrlKey) pressedCombination.push('Ctrl');
        if (event.altKey) pressedCombination.push('Alt');
        if (event.shiftKey) pressedCombination.push('Shift');
        if (!['Control', 'Shift', 'Alt', 'Meta'].includes(event.key)) {
            pressedCombination.push(event.key);
        }

        if (JSON.stringify(pressedCombination) === JSON.stringify(addressPanelKeyCombination)) {
            event.preventDefault();

            let addressPanel = document.querySelector('.full-address-container');
            if (addressPanel) {
                let editButton = addressPanel.querySelector('.edit-button');
                if (editButton) {
                    setTimeout(() => {
                        editButton.click();
                    }, 100);
                } else {
                    console.log("Edit button not found.");
                }
            } else {
                console.log("Address panel not found.");
            }
        }
    }

    function initializeMyUserscript() {
        initializeSidebarTab();
        document.addEventListener('keydown', handleEnterPress, true);
        document.addEventListener('keydown', handleSaveKeyPress, true);
        document.addEventListener('keydown', handleAddressPanelKeyPress, true);
    }

    if (W?.userscripts?.state.isReady) {
        initializeMyUserscript();
    } else {
        document.addEventListener("wme-ready", initializeMyUserscript, { once: true });
    }

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址