您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Automatically and dynamically sets the correct text direction (RTL/LTR) for Persian and English text, including headings, lists, tables, and input fields, in AI chat interfaces without needing a refresh.
// ==UserScript== // @name AI Chat RTL-LTR Fixer (Persian/English) // @namespace http://tampermonkey.net/ // @version 1.6 // @description Automatically and dynamically sets the correct text direction (RTL/LTR) for Persian and English text, including headings, lists, tables, and input fields, in AI chat interfaces without needing a refresh. // @description:fa جهت نوشتار فارسی و انگلیسی را به صورت کاملاً پویا و زنده در محیط چتباتهای هوش مصنوعی (مثل ChatGPT، Gemini و...) اصلاح میکند. شامل اصلاح سرتیترها، لیستها، جدولها و کادرهای ورودی متن بدون نیاز به رفرش. // @author Your Name // @match *://*/* // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; // Regex to detect Persian (Arabic script) characters. const persianRegex = /[\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF]/; // --- Function to Fix Direction for Standard Elements --- function fixDirection(element) { if (!element || element.nodeType !== 1 || element.isContentEditable) { return; } if (element.matches('pre, code, kbd, samp')) { element.style.direction = 'ltr'; element.style.textAlign = 'left'; return; } const hasPersian = persianRegex.test(element.textContent); if (element.matches('p, li, h1, h2, h3, h4, h5, h6, blockquote, table, th, td, div, span')) { if (hasPersian) { if (element.style.direction !== 'rtl') { element.style.direction = 'rtl'; element.style.textAlign = 'right'; } } else { if (!element.querySelector('[style*="direction: rtl"]')) { if (element.style.direction !== 'ltr') { element.style.direction = 'ltr'; element.style.textAlign = 'left'; } } } } } // --- Function to Fix Direction for Input/Textarea Elements --- function fixInputDirection(inputElement) { const isEditable = inputElement.isContentEditable; const value = isEditable ? inputElement.textContent : inputElement.value; if (typeof value === 'undefined') return; const hasPersian = persianRegex.test(value); if (hasPersian) { if (inputElement.style.direction !== 'rtl') { inputElement.style.direction = 'rtl'; inputElement.style.textAlign = 'right'; } } else { if (inputElement.style.direction !== 'ltr') { inputElement.style.direction = 'ltr'; inputElement.style.textAlign = 'left'; } } } // --- Function to Scan the Document and Set Up Listeners --- function scanAndFixAll() { const contentSelectors = 'p, div, span, li, ol, ul, blockquote, table, th, td, h1, h2, h3, h4, h5, h6'; document.querySelectorAll(contentSelectors).forEach(fixDirection); const inputSelectors = 'textarea, input[type="text"], input[type="search"], input:not([type]), [contenteditable="true"]'; document.querySelectorAll(inputSelectors).forEach(input => { if (!input.dataset.rtlFixerAttached) { fixInputDirection(input); input.addEventListener('input', () => fixInputDirection(input)); input.dataset.rtlFixerAttached = 'true'; } }); } // --- MutationObserver to Handle Dynamic Content --- const observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { // Case 1: New nodes are added if (mutation.type === 'childList') { mutation.addedNodes.forEach(function(node) { if (node.nodeType === 1) { fixDirection(node); node.querySelectorAll('*').forEach(fixDirection); } }); } // Case 2: Text content of an existing node changes else if (mutation.type === 'characterData') { if (mutation.target.parentElement) { fixDirection(mutation.target.parentElement); } } }); }); // --- Start the Script --- observer.observe(document.body, { childList: true, subtree: true, characterData: true // IMPORTANT: This watches for text changes }); // Run initial scans to handle content present on load scanAndFixAll(); setTimeout(scanAndFixAll, 500); // For apps that render content after initial load console.log('AI Chat RTL Fixer v1.6 (Dynamic) is active.'); })();