chatgpt-rtl-toggle

enabling RTL (Right-To-Left) text direction toggle

  1. // ==UserScript==
  2. // @name chatgpt-rtl-toggle
  3. // @namespace Violentmonkey Scripts
  4. // @match https://chatgpt.com/*/*
  5. // @grant none
  6. // @version 1.0
  7. // @author -
  8. // @description enabling RTL (Right-To-Left) text direction toggle
  9. // @run-at document-end
  10. // @license MIT
  11. // ==/UserScript==
  12. //
  13. // chrome extention: https://chromewebstore.google.com/detail/chatgpt-rtl/cnhikhicflgjbfnllpmbbdpjcfmfnkii
  14.  
  15. if (!document.getElementById("RTL")) {
  16. const style = document.createElement("style");
  17. style.id = "RTL";
  18. style.innerHTML = `
  19. #rtlButton {
  20. transition: .15s;
  21. cursor: pointer;
  22. }
  23. main.rtl #rtlButton {
  24. transform: rotateY(180deg);
  25. }
  26. code, pre {
  27. direction: ltr;
  28. text-align: left;
  29. }
  30. main form textarea#prompt-textarea {
  31. padding-right: 96px;
  32. }
  33. [class^="react-scroll-to-bottom--css-"] {
  34. height: 100%;
  35. overflow-y: auto;
  36. }
  37. main.rtl p,
  38. main.rtl textarea {
  39. direction: rtl;
  40. }
  41. main.rtl .overflow-x-auto {
  42. overflow-x: unset;
  43. direction: rtl;
  44. }
  45. main.rtl .markdown ul,
  46. main.rtl .markdown ol {
  47. padding-left: unset;
  48. padding-right: 0;
  49. direction: rtl;
  50. }
  51. main.rtl .prose :where(ul):not(:where([class~="not-prose"] *)),
  52. main.rtl .prose :where(ol):not(:where([class~="not-prose"] *)) {
  53. padding-left: unset;
  54. padding-right: 1.625em;
  55. }
  56. main.rtl .markdown ul>li::before,
  57. main.rtl .markdown ol>li::before {
  58. --tw-translate-x: 100%;
  59. padding-right: unset;
  60. padding-left: .5rem;
  61. }
  62. main.rtl .prose :where(ul > li):not(:where([class~="not-prose"] *)),
  63. main.rtl .prose :where(ol > li):not(:where([class~="not-prose"] *)) {
  64. padding-right: .375em;
  65. padding-left: unset;
  66. }
  67. `;
  68. document.head.appendChild(style);
  69. }
  70.  
  71. function addRTLButton(textarea) {
  72. if (!document.getElementById("rtlButton")) {
  73. document.querySelector("main").classList.add("rtl");
  74. const rtlButton = document.createElement("div");
  75. rtlButton.id = "rtlButton";
  76. rtlButton.className = "mb-1 me-1";
  77. rtlButton.innerHTML = `
  78. <div class="relative">
  79. <div class="relative">
  80. <div class="flex flex-col">
  81. <span class="flex" data-state="closed">
  82. <div aria-disabled="false" aria-label="Attach files" class="flex items-center justify-center h-8 w-8 rounded-lg rounded-bl-xl text-token-text-primary dark:text-white focus-visible:outline-black dark:focus-visible:outline-white hover:bg-black/10">
  83. <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
  84. <path d="M7 6H17 M7 10H13 M7 14H17 M7 18H13" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
  85. </svg>
  86. </div>
  87. </span>
  88. </div>
  89. </div>
  90. </div>
  91. `;
  92. textarea.parentElement.parentElement.parentElement.parentElement.lastElementChild.firstElementChild.appendChild(
  93. rtlButton
  94. );
  95. rtlButton.addEventListener("click", () =>
  96. document.querySelector("main").classList.toggle("rtl")
  97. );
  98. }
  99. }
  100.  
  101. const observer = new MutationObserver(() => {
  102. const textarea = document.querySelector("main form textarea");
  103. if (textarea) {
  104. addRTLButton(textarea);
  105. // observer.disconnect();
  106. }
  107. });
  108.  
  109. observer.observe(document.body, {
  110. childList: true,
  111. subtree: true,
  112. });
  113.  
  114.  
  115.  
  116. //chrome extention: https://chromewebstore.google.com/detail/chatgpt-rtl/cnhikhicflgjbfnllpmbbdpjcfmfnkii

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址