דילוג לתוכן

שיתוף | תוסף (סקריפט לTampermonkey) לתיקון שגיאות כתיב אוטמטי לפני שליחה בפורום

אופן השימוש בפורום
11 4 20 4
  • @חובבן-מקצועי תן בראש תותח

  • שלום לכולם.
    שלחתי את זה כבר בפורום מתמחים טופ, וחשבתי שזה יכול להיות יעיל גם פה.

    לפעמים קורה שאנשים כותבים מהר, או שפחות מתאמצים שהטקסט יהיה כתוב נכון מבחינה דקדוקית, ולפעמים זה ממש מקשה על הקוראים להבין את מה שנכתב.

    לו נוח לקרו טקסט עם מלה שגיות קתיב...

    קיצור.. בניתי סקריפט (למה עדיף סקריפט? מהסיבות שנכתבו פה..)

    הסקריפט (בספויילר):

    // ==UserScript==
    // @name         מתקן שגיאות חכם - מתמחים טופ (מבוסס Gemini)
    // @namespace    http://tampermonkey.net/
    // @version      3.0
    // @description  תיקון שגיאות כתיב אוטומטי לפני שליחת הודעה, כולל חלון תצוגה מתקדם והגנה מלאה על ציטוטים.
    // @author       @חובבן מקצועי (בסיוע Gemini)
    // @match         https://*.bina.top/*
    // @grant        GM_getValue
    // @grant        GM_setValue
    // @grant        GM_xmlhttpRequest
    // @connect      generativelanguage.googleapis.com
    // ==/UserScript==
    
    (function() {
        'use strict';
    
        function getApiKey() {
            let key = GM_getValue('gemma_api_key', null);
            if (!key) {
                key = prompt("הכנס מפתח API עבור Gemini:");
                if (key) {
                    key = key.trim();
                    GM_setValue('gemma_api_key', key);
                }
            }
            return key;
        }
    
        async function checkSpelling(text) {
            const apiKey = getApiKey();
            if (!apiKey) return null;
    
            const url = `https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-flash-lite-preview:generateContent?key=${apiKey}`;
    
            const systemInstruction = `
    תפקיד: בודק שגיאות כתיב (Spell Checker) בלבד.
    
    חוקי ברזל:
    1. **אסור לשנות סגנון, תחביר או פיסוק!** תקן אך ורק הקלדות שגויות (Typos) ושגיאות כתיב מובהקות.
    2. **התעלמות מוחלטת מציטוטים:** שורות שמתחילות בתו ">" (גדול מ...) הן ציטוטים. **אסור לך לגעת בהן, אסור לך לתקן בהן שגיאות כתיב, ואסור לך בשום אופן לדווח על שגיאות שמצאת בהן ברשימת השינויים.** העתק אותן בדיוק מוחלט כפי שהן.
    3. **מבנה תשובה:** א. אם לא ביצעת אף תיקון (או אם כל הטקסט הוא ציטוט), החזר רק את המילה: "תקין".
       ב. אם מצאת שגיאת כתיב (שאינה בציטוט) ותיקנת אותה, החזר את הטקסט המלא המתוקן, הוסף שורה חדשה עם "***", ומתחתיה ציין אך ורק את המילים שבאמת שינית.
    `;
    
            const payload = {
                systemInstruction: { parts: [{ text: systemInstruction }] },
                contents: [{ role: "user", parts: [{ text: text }] }]
            };
    
            return new Promise((resolve) => {
                GM_xmlhttpRequest({
                    method: "POST",
                    url: url,
                    headers: { "Content-Type": "application/json" },
                    data: JSON.stringify(payload),
                    onload: function(response) {
                        try {
                            if (response.status !== 200) return resolve(null);
                            const data = JSON.parse(response.responseText);
                            if (data?.candidates?.[0]?.content?.parts?.[0]?.text) {
                                resolve(data.candidates[0].content.parts[0].text.trim());
                            } else {
                                resolve(null);
                            }
                        } catch (e) { resolve(null); }
                    },
                    onerror: function() { resolve(null); }
                });
            });
        }
    
        function showCustomDialog(cleanText, changeLogs, onAccept, onReject, onCancel) {
            const dialog = document.createElement('dialog');
            dialog.style.cssText = 'border:none; border-radius:8px; box-shadow:0 10px 25px rgba(0,0,0,0.2); padding:20px; width:90%; max-width:500px; font-family:system-ui, sans-serif; direction:rtl; background:#fff; color:#333; z-index:9999; position:relative;';
    
            const title = document.createElement('h3');
            title.textContent = 'הצעת תיקון מ-Gemini';
            title.style.cssText = 'margin-top:0; color:#2c3e50; font-size:18px; font-weight:bold; border-bottom:2px solid #f0f0f0; padding-bottom:10px;';
    
            const textDiv = document.createElement('div');
            textDiv.style.cssText = 'background:#f8f9fa; padding:12px; border-radius:6px; max-height:200px; overflow-y:auto; font-size:14px; margin-bottom:15px; border: 1px solid #e9ecef; white-space: pre-wrap; line-height: 1.5; color:#212529;';
            textDiv.textContent = cleanText;
    
            const changesTitle = document.createElement('h4');
            changesTitle.textContent = 'פירוט השינויים:';
            changesTitle.style.cssText = 'margin:0 0 8px 0; font-size:14px; color:#555; font-weight:bold;';
    
            const logsDiv = document.createElement('div');
            logsDiv.style.cssText = 'font-size:13px; color:#666; margin-bottom:20px; white-space:pre-wrap; line-height: 1.4;';
            logsDiv.textContent = changeLogs;
    
            const btnContainer = document.createElement('div');
            btnContainer.style.cssText = 'display:flex; gap:10px; justify-content:flex-end; flex-wrap:wrap; margin-bottom: 10px;';
    
            const btnCancel = document.createElement('button');
            btnCancel.textContent = 'ביטול (חזור לעריכה)';
            btnCancel.style.cssText = 'padding:8px 14px; background:#e0e0e0; border:none; border-radius:4px; cursor:pointer; color:#333; font-weight:bold; transition: 0.2s;';
            btnCancel.onmouseover = () => btnCancel.style.background = '#d0d0d0';
            btnCancel.onmouseout = () => btnCancel.style.background = '#e0e0e0';
    
            const btnReject = document.createElement('button');
            btnReject.textContent = 'שלח מקורי (עם השגיאות)';
            btnReject.style.cssText = 'padding:8px 14px; background:#e74c3c; color:#fff; border:none; border-radius:4px; cursor:pointer; font-weight:bold; transition: 0.2s;';
            btnReject.onmouseover = () => btnReject.style.background = '#c0392b';
            btnReject.onmouseout = () => btnReject.style.background = '#e74c3c';
    
            const btnAccept = document.createElement('button');
            btnAccept.textContent = 'שמור תיקונים ושלח';
            btnAccept.style.cssText = 'padding:8px 14px; background:#27ae60; color:#fff; border:none; border-radius:4px; cursor:pointer; font-weight:bold; transition: 0.2s;';
            btnAccept.onmouseover = () => btnAccept.style.background = '#219653';
            btnAccept.onmouseout = () => btnAccept.style.background = '#27ae60';
    
            btnContainer.append(btnAccept, btnReject, btnCancel);
    
            // הוספת הקרדיט בתחתית החלון
            const creditDiv = document.createElement('div');
            creditDiv.textContent = 'פותח ע"י @חובבן מקצועי';
            creditDiv.style.cssText = 'font-size: 11px; color: #a0a0a0; text-align: left; margin-top: 15px; border-top: 1px solid #f0f0f0; padding-top: 5px; user-select: none;';
    
            dialog.append(title, textDiv, changesTitle, logsDiv, btnContainer, creditDiv);
            document.body.appendChild(dialog);
    
            btnAccept.onclick = () => { dialog.close(); onAccept(); };
            btnReject.onclick = () => { dialog.close(); onReject(); };
            btnCancel.onclick = () => { dialog.close(); onCancel(); };
    
            dialog.addEventListener('close', () => dialog.remove());
            dialog.showModal();
        }
    
        document.addEventListener('click', async function(e) {
            const sendBtn = e.target.closest('.composer-submit');
            if (!sendBtn || sendBtn.dataset.verified === "true") return;
    
            const textarea = document.querySelector('.composer .write');
            if (!textarea || !textarea.value.trim()) return;
    
            e.preventDefault();
            e.stopImmediatePropagation();
    
            const originalText = textarea.value;
    
            const iconElement = sendBtn.querySelector('i.fa');
            let originalIconClass = "";
            if (iconElement) {
                originalIconClass = iconElement.className;
                iconElement.className = 'fa fa-spinner fa-spin';
            }
            sendBtn.classList.add('disabled');
            sendBtn.style.pointerEvents = 'none';
    
            const textNode = Array.from(sendBtn.childNodes).find(node => node.nodeType === Node.TEXT_NODE && node.textContent.trim() !== "");
            let originalTextContent = textNode ? textNode.textContent : "";
            if (textNode) textNode.textContent = " מוודא כתיב... ";
    
            let result = await checkSpelling(originalText);
    
            if (iconElement) iconElement.className = originalIconClass;
            if (textNode) textNode.textContent = originalTextContent;
            sendBtn.classList.remove('disabled');
            sendBtn.style.pointerEvents = 'auto';
    
            if (!result || result === "תקין" || result === originalText) {
                submitForm(sendBtn);
            } else {
                const parts = result.split('***');
                let cleanText = parts[0].trim();
                let changeLogs = parts[1] ? parts[1].trim() : "בוצעו תיקוני כתיב";
    
                if (cleanText === originalText.trim()) {
                    submitForm(sendBtn);
                    return;
                }
    
                showCustomDialog(
                    cleanText,
                    changeLogs,
                    () => {
                        textarea.value = cleanText;
                        textarea.dispatchEvent(new Event('input', { bubbles: true }));
                        textarea.dispatchEvent(new Event('change', { bubbles: true }));
                        submitForm(sendBtn);
                    },
                    () => submitForm(sendBtn),
                    () => {}
                );
            }
        }, true);
    
        function submitForm(btn) {
            btn.dataset.verified = "true";
            btn.click();
            setTimeout(() => { delete btn.dataset.verified; }, 1500);
        }
    })();
    

    הביצוע ממש פשוט - תריצו את זה על tampermonkey - יש לזה מדריך פה.
    קודם כל תצטרכו להוציא מפתח api מAI סטודיו.
    בפעם הראשונה יקפוץ לכם חלון בו אתם מדביקים את הkey שקיבלתם. וייתכן ותצטרכו לאשר אותו שוב.. (יפתח לכם חלון קופץ - בו אתם מאשרים שוב. זאת בלי קשר למדריך שתסתכלו איך מריצים בכלל סקריפטים..)
    ואז לאחר מכן - כל פוסט שתלחצו עליו בכפתור 'שליחה' - הוא יחשוב כמה שניות - ואז יציע לכם את התיקונים הנדרשים.. עם אפשרות לשליחה עם התיקונים / חזרה לעריכה / ושליחה בלי תיקונים.

    4d856908-2992-48f0-bb63-085a5d3fcef8-image.jpeg

    משתמש יקר - אם אתה יודע שלעיתים קרובות (ואולי גם קצת רחוקות) אתה נוטה לכתוב עם שגיאות כתיב - באמת לטובתך (וכמובן לטובת כלל הפורום) - כדאי שתתקין סקריפט זה, זה גם יעזור לכולם - וגם יכבד אותך. זה שווה את זמן ההמתנה בין הכתיבה לשליחה בפועל.. בתודה מראש!

    שימו לב - התוסף עובד רק כאשר לוחצים על כפתור שלח, ולא כשמשתמים בקיצור המקלדת CTRL + ENTER

    מי שככבר התקין את התוסף הזה במתמחים, ורוצה שזה יהיה בשתי הפורומים, אפשר פשוט להוסיף שורה נוספת שבה יהיה כתוב

    // @match         https://*.bina.top/*
    

    וכך למעשה לחסוך כפילות קודים.

    2debf720-e4ba-4f8e-8068-a6751dbb3494-image.jpeg

    @חובבן-מקצועי
    אתה יכול לצרף קישור לסקריפט?

  • @חובבן-מקצועי
    אתה יכול לצרף קישור לסקריפט?

    @אלוף-בטכנולוגיה למה אתה מתכוון? אתה רוצה שאוסיף את זה למאגר מקוון ? (כי כרגע זה לא נמצא בשום מאגר, ופשוט הבאתי את הקוד של הסקריפט)

  • @אלוף-בטכנולוגיה למה אתה מתכוון? אתה רוצה שאוסיף את זה למאגר מקוון ? (כי כרגע זה לא נמצא בשום מאגר, ופשוט הבאתי את הקוד של הסקריפט)

    @חובבן-מקצועי
    אני לא בדיוק מבין בזה ואני לא יודע מה עושים עם הקוד הזה...
    בינתיים בכל הסקריפטים שהתקנתי הביאו קישור...

    סליחה על הבורות...😞

  • @חובבן-מקצועי
    אני לא בדיוק מבין בזה ואני לא יודע מה עושים עם הקוד הזה...
    בינתיים בכל הסקריפטים שהתקנתי הביאו קישור...

    סליחה על הבורות...😞

    @אלוף-בטכנולוגיה אוקי, בשביל זה הבאתי קישור למדריך במתמחים טופ.

  • פוסט זה נמחק!
  • פוסט זה נמחק!
  • @אלוף-בטכנולוגיה אוקי, בשביל זה הבאתי קישור למדריך במתמחים טופ.

    @חובבן-מקצועי
    בסדר הצלחתי תודה!

  • אפשר להחליט לבד איזה תיקון להחיל ואיזה לא?

  • אפשר להחליט לבד איזה תיקון להחיל ואיזה לא?

    @בינארי-חכם לא, אתה יכול לראות מה הוא שינה, ולפי זה ללמוד מה עליך לתקן, ואז לשנות ולשלוח בלי תיקון.


קרא עוד