Загрузка данных
// ==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();
});
})();