chatGPT for Persians (Professional rtl, Easy shortkeys, Support multi language and for coder users)

Fix rtl text issues for Persian/Farsi language. Press R+RIGHT for full rtl. R+LEFT for rtl align left. and R + DOWN for deactivation.

  1. // ==UserScript==
  2. // @name chatGPT for Persians (Professional rtl, Easy shortkeys, Support multi language and for coder users)
  3. // @name:fa راست چین chatgpt
  4. // @description Fix rtl text issues for Persian/Farsi language. Press R+RIGHT for full rtl. R+LEFT for rtl align left. and R + DOWN for deactivation.
  5. // @description:fa محیط چت جی پی تی رو راست چین میکنه و برای بلاک های کدینگ و استفاده ترکیبی دو زبانه بهینه شده. از دکمه های ترکیبی R و چپ R و راست و R پایین استفاده کنید.
  6. // @version 1.3
  7. // @namespace NIMABEHKARrtlchatgpt
  8. // @grant none
  9. // @author Nima Behkar
  10. // @license CC BY-NC-SA 4.0 DEED
  11. // @match *://chat.openai.com/*
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16.  
  17. const styles = {
  18. 'rtlLeft': `
  19. body *:not(code):not(code *) {
  20. direction: rtl;
  21. text-align: left;
  22. }
  23. .z-0 {
  24. direction: ltr;
  25. }
  26. .scrollbar-trigger div {
  27. text-align: left;
  28. }
  29. pre, pre *, code, code * {
  30. direction: ltr !important;
  31. text-align: left !important;
  32. }
  33. `,
  34. 'rtlRight': `
  35. body *:not(code):not(code *) {
  36. direction: rtl;
  37. text-align: right;
  38. }
  39. .z-0 {
  40. direction: ltr;
  41. }
  42. .scrollbar-trigger div {
  43. text-align: left;
  44. }
  45. pre, pre *, code, code * {
  46. direction: ltr !important;
  47. text-align: left !important;
  48. }
  49. .prose {
  50. padding-left: 0 !important;
  51. }
  52. .markdown ol,ul {
  53. padding-right: 1em !important;
  54. list-style-type: auto !important;
  55. }
  56. li {
  57. display: list-item !important;
  58. }
  59. li:before {
  60. content: '' !important;
  61. }
  62. `
  63. };
  64.  
  65. const styleSheet = document.createElement('style');
  66. styleSheet.type = 'text/css';
  67. document.head.appendChild(styleSheet);
  68.  
  69. let currentStyle = '';
  70.  
  71. const FapplyStyle = (styleName) => {
  72. if (styles[styleName]) {
  73. styleSheet.innerText = styles[styleName];
  74. currentStyle = styleName;
  75. }
  76. };
  77.  
  78. const applyStyle = (styleName) => {
  79. if (styles[styleName]) {
  80. styleSheet.innerText = styles[styleName];
  81. currentStyle = styleName;
  82. alert(`استایل "${styleName}" فعال شد.`);
  83. }
  84. };
  85.  
  86. const disableStyle = () => {
  87. styleSheet.innerText = '';
  88. currentStyle = '';
  89. alert('استایل غیرفعال شد.');
  90. };
  91.  
  92. let lastKeyPressed = '';
  93.  
  94. document.addEventListener('keydown', (event) => {
  95. if (event.key === 'r' || event.key === 'ArrowLeft' || event.key === 'ArrowRight' || event.key === 'ArrowDown') {
  96. if (lastKeyPressed === 'r' && event.key === 'ArrowLeft') {
  97. applyStyle('rtlLeft');
  98. } else if (lastKeyPressed === 'r' && event.key === 'ArrowRight') {
  99. applyStyle('rtlRight');
  100. } else if (lastKeyPressed === 'r' && event.key === 'ArrowDown') {
  101. if (currentStyle) {
  102. disableStyle();
  103. }
  104. }
  105. lastKeyPressed = event.key;
  106. }
  107. });
  108.  
  109. document.addEventListener('keyup', (event) => {
  110. if (event.key === lastKeyPressed) {
  111. lastKeyPressed = '';
  112. }
  113. });
  114.  
  115. window.onload = () => {
  116. FapplyStyle('rtlRight');
  117. };
  118. })();