Загрузка данных


// ==UserScript==
// @name         Canned Responses (Custom)
// @namespace    local.canned.responses
// @version      1.0
// @description  Right-click canned responses with add/remove support
// @match        *://*/*
// @grant        GM_getValue
// @grant        GM_setValue
// ==/UserScript==

(function () {
    'use strict';

    let menu;

    function getResponses() {
        return GM_getValue("responses", []);
    }

    function saveResponses(responses) {
        GM_setValue("responses", responses);
    }

    function addResponse(text) {
        let list = getResponses();
        list.push(text);
        saveResponses(list);
    }

    function deleteResponse(index) {
        let list = getResponses();
        list.splice(index, 1);
        saveResponses(list);
    }

    function insertText(text) {
        let el = document.activeElement;
        if (!el) return;

        if (el.tagName === "TEXTAREA" || el.tagName === "INPUT") {
            let start = el.selectionStart || 0;
            let end = el.selectionEnd || 0;

            let value = el.value || "";
            el.value = value.slice(0, start) + text + value.slice(end);

            el.selectionStart = el.selectionEnd = start + text.length;
        } else {
            document.execCommand("insertText", false, text);
        }
    }

    function createMenu(x, y) {
        removeMenu();

        menu = document.createElement("div");
        menu.style.position = "fixed";
        menu.style.top = y + "px";
        menu.style.left = x + "px";
        menu.style.background = "#222";
        menu.style.color = "#fff";
        menu.style.padding = "8px";
        menu.style.zIndex = 999999;
        menu.style.borderRadius = "6px";
        menu.style.minWidth = "200px";
        menu.style.fontSize = "14px";

        let title = document.createElement("div");
        title.innerText = "Canned Responses";
        title.style.fontWeight = "bold";
        title.style.marginBottom = "6px";
        menu.appendChild(title);

        let list = getResponses();

        if (list.length === 0) {
            let empty = document.createElement("div");
            empty.innerText = "No items";
            empty.style.opacity = "0.7";
            menu.appendChild(empty);
        }

        list.forEach((item, i) => {
            let row = document.createElement("div");
            row.style.display = "flex";
            row.style.justifyContent = "space-between";
            row.style.marginBottom = "4px";

            let btn = document.createElement("div");
            btn.innerText = item;
            btn.style.cursor = "pointer";
            btn.style.flex = "1";

            btn.onclick = () => {
                insertText(item);
                removeMenu();
            };

            let del = document.createElement("span");
            del.innerText = "✖";
            del.style.cursor = "pointer";
            del.style.marginLeft = "8px";
            del.style.color = "red";

            del.onclick = (e) => {
                e.stopPropagation();
                deleteResponse(i);
                createMenu(x, y);
            };

            row.appendChild(btn);
            row.appendChild(del);
            menu.appendChild(row);
        });

        let addBtn = document.createElement("div");
        addBtn.innerText = "+ Add new";
        addBtn.style.marginTop = "8px";
        addBtn.style.cursor = "pointer";
        addBtn.style.color = "#0f0";

        addBtn.onclick = () => {
            let text = prompt("New response:");
            if (text) {
                addResponse(text);
                createMenu(x, y);
            }
        };

        menu.appendChild(addBtn);

        document.body.appendChild(menu);
    }

    function removeMenu() {
        if (menu) menu.remove();
        menu = null;
    }

    document.addEventListener("contextmenu", function (e) {
        removeMenu();
        createMenu(e.clientX, e.clientY);
        e.preventDefault();
    });

    document.addEventListener("click", function () {
        removeMenu();
    });

})();