// ==UserScript== // @name מעצב פוסטים אוטומטי - בינה טופ // @namespace http://tampermonkey.net/ // @version 1.4 // @description עיצוב פוסטים אוטומטי באמצעות AI בפורום בינה טופ // @author מייבין במקצת // @match https://bina.top/* // @grant GM_setValue // @grant GM_getValue // @run-at document-end // ==/UserScript== (function() { 'use strict'; function injectAiButton() { const formattingBar = document.querySelector('.formatting-bar'); if (!formattingBar || formattingBar.querySelector('.gemini-format-wrapper')) return; // מציאת כפתור העלאת קובץ כדי למקם את הכפתור החדש לידו let fileBtnNodes = Array.from(formattingBar.querySelectorAll('li[aria-label="העלאת קובץ"], li[data-bs-original-title="העלאת קובץ"], .fa-file-o')); let referenceNode = null; if (fileBtnNodes.length > 0) { referenceNode = fileBtnNodes[0].closest('li'); } if (!referenceNode) return; // שכפול ה-li המקורי let aiWrapper = referenceNode.cloneNode(true); aiWrapper.classList.add('gemini-format-wrapper'); // 1. ניקוי מוחלט של שאריות טולטיפ ישן כדי למנוע התנגשויות aiWrapper.removeAttribute('aria-describedby'); aiWrapper.removeAttribute('data-bs-original-title'); aiWrapper.removeAttribute('aria-label'); // סידור הכפתור הפנימי let innerBtn = aiWrapper.querySelector('button'); if (innerBtn) { innerBtn.removeAttribute('data-format'); innerBtn.removeAttribute('data-action'); innerBtn.removeAttribute('id'); innerBtn.removeAttribute('aria-describedby'); innerBtn.removeAttribute('data-bs-original-title'); innerBtn.removeAttribute('aria-label'); innerBtn.style.cursor = 'pointer'; } // הטמעת ה-SVG המבוקש בגודל גדול ופרופורציונלי (18x18px) שמתיישב במרכז let iconEl = aiWrapper.querySelector('i.fa') || aiWrapper.querySelector('svg'); if (iconEl) { iconEl.outerHTML = ``; } // הוספה לבר הכלים referenceNode.parentNode.insertBefore(aiWrapper, referenceNode.nextSibling); // 2. הפעלה אקטיבית של הטולטיפ השחור המקורי של הפורום (Bootstrap Tooltip) const tooltipText = 'עיצוב פוסט אוטומטי באמצעות AI'; aiWrapper.setAttribute('title', tooltipText); aiWrapper.setAttribute('data-bs-toggle', 'tooltip'); setTimeout(() => { // תומך בגרסאות שונות של Bootstrap המוטמעות ב-NodeBB if (typeof window.bootstrap !== 'undefined' && window.bootstrap.Tooltip) { new window.bootstrap.Tooltip(aiWrapper, { title: tooltipText, trigger: 'hover', placement: 'bottom' }); } else if (typeof window.$ !== 'undefined' && window.$.fn && window.$.fn.tooltip) { window.$(aiWrapper).tooltip({ title: tooltipText, trigger: 'hover', placement: 'bottom' }); } }, 300); // אירוע לחיצה והפעלת ה-AI aiWrapper.addEventListener('click', async (e) => { e.preventDefault(); e.stopPropagation(); // הסתרת הטולטיפ בזמן לחיצה if (typeof window.bootstrap !== 'undefined' && window.bootstrap.Tooltip) { let tooltipInstance = window.bootstrap.Tooltip.getInstance(aiWrapper); if (tooltipInstance) tooltipInstance.hide(); } const textarea = document.querySelector('textarea.write'); if (!textarea) return; const originalText = textarea.value.trim(); if (!originalText) { alert('אנא כתוב קודם טקסט בתיבת הפוסט.'); return; } let apiKey = GM_getValue('gemini_api_key'); if (!apiKey) { apiKey = prompt('אנא הזן את מפתח ה-API של Gemini שלך:'); if (!apiKey) return; GM_setValue('gemini_api_key', apiKey); } aiWrapper.style.opacity = '0.5'; aiWrapper.style.pointerEvents = 'none'; const promptText = `תהפוך את הטקסט הבא לפוסט Markdown (MD) מעוצב ומרשים לפורום NodeBB. שמור על התוכן המקורי בלי לשנות או להוסיף תוכן או ניסוח בשום פנים ואופן! ואפילו לא במילה אחת!!!!!. אם יש פיסוק קיים - שמור עליו. אם אין פיסוק - הוסף פיסוק תקין בעברית. השתמש בכל אפשרויות העיצוב הנתמכות בפורום כשמתאים: כותרות, טקסט מודגש, רשימות תבליטים, קוד, קישורים, ורווחים נכונים. הטקסט: ${originalText}`; try { const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-flash-lite-preview:generateContent?key=${apiKey}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ systemInstruction: { parts:[{ text: "אתה מעצב טקסטים. עליך להחזיר אך ורק את הפוסט המעוצב בפורמט Markdown. אסור לך בשום פנים ואופן לכתוב מילות הקדמה (כמו 'להלן הטקסט'), אסור לכתוב סיכומים ואסור להוסיף שום מילה שלא קשורה לתוכן הפוסט. פשוט החזר את הקוד הנקי בלבד." }] }, contents: [{ parts: [{ text: promptText }] }], generationConfig: { temperature: 0.1 } }) }); const data = await response.json(); if (data.candidates && data.candidates[0].content.parts[0].text) { let aiResult = data.candidates[0].content.parts[0].text; aiResult = aiResult.replace(/^```(markdown|md)?\n?/i, '').replace(/\n?```$/i, ''); textarea.value = aiResult; textarea.dispatchEvent(new Event('input', { bubbles: true })); textarea.dispatchEvent(new Event('change', { bubbles: true })); } else { throw new Error(data.error?.message || 'שגיאה לא ידועה.'); } } catch (error) { alert('שגיאה: ' + error.message); if (error.message.includes('API key')) GM_setValue('gemini_api_key', ''); } finally { aiWrapper.style.opacity = '1'; aiWrapper.style.pointerEvents = 'auto'; } }); } const observer = new MutationObserver(() => { if (document.querySelector('.formatting-bar') && !document.querySelector('.gemini-format-wrapper')) { injectAiButton(); } }); observer.observe(document.body, { childList: true, subtree: true }); })();