AI Grammar Checker (Grammarly Alternative) for Violentmonkey

Checks grammar and spelling in text inputs (Like Grammarly Premium! With manual dismissal!)

目前為 2025-02-13 提交的版本,檢視 最新版本

// ==UserScript==
// @name         AI Grammar Checker (Grammarly Alternative) for Violentmonkey
// @namespace    http://violentmonkey.net/
// @version      1.3
// @description  Checks grammar and spelling in text inputs (Like Grammarly Premium! With manual dismissal!)
// @author       You
// @match        *://*/*
// @grant        GM_xmlhttpRequest
// @connect      api.languagetool.org
// ==/UserScript==

var GrammarChecker = {};

GrammarChecker.API_URL = "https://api.languagetool.org/v2/check";

GrammarChecker.init = function() {
    console.log("🚀 Grammar Checker Loaded for Violentmonkey!");

    // Observe text inputs and editable divs
    let observer = new MutationObserver(() => {
        document.querySelectorAll("textarea, input[type='text'], [contenteditable='true']").forEach(element => {
            if (!element.dataset.grammarChecked) {
                element.dataset.grammarChecked = "true";
                element.addEventListener("blur", () => GrammarChecker.checkGrammar(element));
            }
        });
    });

    observer.observe(document.body, { childList: true, subtree: true });
};

GrammarChecker.checkGrammar = function(element) {
    let text = element.value || element.innerText;
    if (!text.trim()) return;

    console.log("📝 Checking grammar for:", text);

    GM_xmlhttpRequest({
        method: "POST",
        url: GrammarChecker.API_URL,
        headers: { "Content-Type": "application/x-www-form-urlencoded" },
        data: `language=en-US&text=${encodeURIComponent(text)}`,
        onload: function(response) {
            if (response.status === 200) {
                let data = JSON.parse(response.responseText);
                GrammarChecker.showCorrections(element, data);
            } else {
                console.error("❌ API Error:", response.statusText);
            }
        },
        onerror: function(error) {
            console.error("❌ Network Error:", error);
        }
    });
};

GrammarChecker.showCorrections = function(element, data) {
    let errors = data.matches;
    if (errors.length === 0) {
        console.log("✅ No errors found.");
        return;
    }

    // Remove old tooltips before adding a new one
    document.querySelectorAll(".grammar-tooltip").forEach(e => e.remove());

    let tooltip = document.createElement("div");
    tooltip.className = "grammar-tooltip";

    let suggestions = errors.map(e => `${e.message} ➝ ${e.replacements.map(r => r.value).join(", ")}`).join("\n");

    let textNode = document.createElement("p");
    textNode.innerText = suggestions;
    tooltip.appendChild(textNode);

    // Add "OK" button to close the tooltip
    let okButton = document.createElement("button");
    okButton.innerText = "OK";
    okButton.style.marginTop = "5px";
    okButton.style.padding = "5px 10px";
    okButton.style.background = "#f39c12";
    okButton.style.border = "none";
    okButton.style.cursor = "pointer";
    okButton.style.color = "#fff";
    okButton.style.fontWeight = "bold";

    okButton.addEventListener("click", () => {
        tooltip.remove();
    });

    tooltip.appendChild(okButton);

    // Style the tooltip
    tooltip.style.position = "absolute";
    tooltip.style.background = "#fffa65";
    tooltip.style.color = "#333";
    tooltip.style.border = "1px solid #f39c12";
    tooltip.style.padding = "10px";
    tooltip.style.zIndex = "9999";
    tooltip.style.maxWidth = "300px";
    tooltip.style.fontSize = "14px";
    tooltip.style.top = `${element.getBoundingClientRect().bottom + window.scrollY}px`;
    tooltip.style.left = `${element.getBoundingClientRect().left}px`;

    document.body.appendChild(tooltip);
};

// Start the script
GrammarChecker.init();


QingJ © 2025

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