Update Chatgpt-RTL.user.js

This commit is contained in:
HUSSEIN
2025-09-25 19:07:30 +03:30
committed by GitHub
parent 75a0fca61f
commit f98ae446d1
+63 -71
View File
@@ -1,91 +1,83 @@
// ==UserScript== // ==UserScript==
// @name ChatGPT RTL // @name ChatGPT RTL
// @namespace http://chat.openai.com // @namespace http://chat.openai.com
// @namespace http://deepseek.com
// @author Alireza Farzaneh // @author Alireza Farzaneh
// @version 0.1.2 // @version 0.1.2.1
// @description Fixes the direction of RTL languages in ChatGPT's interface // @description Fixes the direction of RTL languages in LLM's interface
// @match https://chat.openai.com/* // @match https://chat.openai.com/*
// @match https://chatgpt.com/* // @match https://chatgpt.com/*
// @match https://chat.deepseek.com/*
// @match https://claude.ai/*
// @match https://chat.qwen.ai/*
// @grant none // @grant none
// ==/UserScript== // ==/UserScript==
;(function() { ;(function() {
"use strict"; "use strict";
const RTL_REGEX = /[\u0590-\u05FF\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/;
var PERSIAN_REGEX = /[\u0600-\u06FF]/;
var HEBREW_REGEX = /[\u0590-\u05FF]/;
var ARABIC_REGEX = /[\u0600-\u06FF]/;
var RTL_REGEX = new RegExp([PERSIAN_REGEX.source, HEBREW_REGEX.source, ARABIC_REGEX.source].join("|"));
function containsRTLText(text) { const styleId = 'deepseek-rtl-fix-style';
return RTL_REGEX.test(text); if (!document.getElementById(styleId)) {
const style = document.createElement('style');
style.id = styleId;
style.textContent = `
.deepseek-rtl-applied, .deepseek-rtl-applied * {
direction: rtl !important;
text-align: right !important;
}
`;
document.head.appendChild(style);
} }
function changeTextElementDirection(element) { function applyRTLToNode(node) {
if (element.parentNode) { if (!node) return;
const parentElement = element.parentNode; let elem = null;
parentElement.setAttribute('dir', 'rtl'); if (node.nodeType === Node.TEXT_NODE) {
parentElement.style.cssText += 'text-align: right !important; direction: rtl !important;'; elem = node.parentElement;
} else if (node.nodeType === Node.ELEMENT_NODE) {
// Apply to parent containers to ensure proper alignment elem = node;
let currentElement = parentElement; }
while (currentElement && currentElement !== document.body) { if (!elem) return;
if (currentElement.classList.contains('markdown-content') ||
currentElement.classList.contains('text-message') || if (elem.closest('.deepseek-rtl-applied')) return;
/^H[1-6]$/.test(currentElement.tagName)) {
currentElement.style.cssText += 'text-align: right !important; direction: rtl !important;'; const txt = elem.textContent || "";
if (RTL_REGEX.test(txt)) {
elem.classList.add('deepseek-rtl-applied');
}
}
function initialScan(root) {
if (!root) root = document.body;
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null, false);
let cur;
while ((cur = walker.nextNode())) {
applyRTLToNode(cur);
}
}
initialScan(document.body);
const observer = new MutationObserver((mutations) => {
for (const mut of mutations) {
if (mut.type === 'childList') {
for (const nd of mut.addedNodes) {
applyRTLToNode(nd);
if (nd.nodeType === Node.ELEMENT_NODE) {
initialScan(nd);
}
} }
currentElement = currentElement.parentElement; } else if (mut.type === 'characterData') {
applyRTLToNode(mut.target);
} }
} }
} });
function isAlreadyModified(element) { observer.observe(document.body, {
return element.parentNode.getAttribute('dir') === 'rtl'; childList: true,
} subtree: true,
characterData: true
});
function modifyPersianTextElements(element) {
if (element === document.body) {
const style = document.createElement('style');
style.textContent = `
.markdown-content, .text-message,
.markdown-content h1, .markdown-content h2,
.markdown-content h3, .markdown-content h4,
.markdown-content h5, .markdown-content h6,
.markdown-content p, .markdown-content div,
[dir="rtl"] {
text-align: right !important;
direction: rtl !important;
}
`;
document.head.appendChild(style);
}
var childNodes = element.childNodes;
for (var i = 0; i < childNodes.length; i++) {
var childNode = childNodes[i];
if (childNode.nodeType === Node.TEXT_NODE) {
if (isAlreadyModified(childNode)) {
continue;
}
if (containsRTLText(childNode.textContent)) {
changeTextElementDirection(childNode);
}
} else if (childNode.nodeType === Node.ELEMENT_NODE) {
modifyPersianTextElements(childNode);
}
}
}
function handleMutations(mutationsList) {
for (let i = 0; i < mutationsList.length; i++) {
const mutation = mutationsList[i];
modifyPersianTextElements(mutation.target.parentNode);
}
};
modifyPersianTextElements(document.body);
var observer = new MutationObserver(handleMutations);
observer.observe(document.body, { childList: true, subtree: true, attributes: true, characterData: true });
})(); })();