ChatGPT Preserve Prompt Textarea

To preserve last typed prompt messages for chat being switched

  1. // ==UserScript==
  2. // @name ChatGPT Preserve Prompt Textarea
  3. // @namespace UserScript
  4. // @match https://chat.openai.com/*
  5. // @grant none
  6. // @version 0.1.4
  7. // @author CY Fung
  8. // @license MIT
  9. // @run-at document-idle
  10. // @description To preserve last typed prompt messages for chat being switched
  11. // ==/UserScript==
  12.  
  13. (() => {
  14. let tzz = 0;
  15. let jKey = null;
  16. let jValue = null;
  17. let isValid = () => { return false; }
  18. const map = new Map();
  19. (async () => {
  20. let wPathname = null;
  21. while (true) {
  22. await new Promise(r => requestAnimationFrame(r));
  23. let sPathname = location.pathname;
  24. if (wPathname === sPathname) continue;
  25. wPathname = sPathname;
  26.  
  27. const vKey = jKey;
  28. const vValue = jValue;
  29. if (vKey) {
  30. Promise.resolve().then(() => {
  31. map.set(vKey, vValue);
  32. });
  33. }
  34. jKey = null;
  35. jValue = null;
  36.  
  37. let tid = tzz;
  38. isValid = () => { return false }
  39. let expired = Date.now() + 200;
  40. while (Date.now() < expired) {
  41. let textarea = document.querySelector('textarea#prompt-textarea');
  42. if (textarea && !textarea.value) break;
  43. if (location.pathname !== sPathname) break;
  44. await new Promise(r => requestAnimationFrame(r));
  45. if (tid !== tzz) break;
  46. }
  47. if (location.pathname !== sPathname) continue;
  48. expired = Date.now() + 80;
  49. let s = map.get(location.pathname);
  50. if (s) {
  51. while (Date.now() < expired) {
  52. let textarea = document.querySelector('textarea#prompt-textarea');
  53. if (!textarea) break;
  54. if (location.pathname !== sPathname) break;
  55. if (textarea.value !== s && tid === tzz) textarea.value = s;
  56. await new Promise(r => requestAnimationFrame(r));
  57. if (tid !== tzz) break;
  58. }
  59. let textarea = document.querySelector('textarea#prompt-textarea');
  60. if (textarea && tid === tzz) {
  61. textarea.focus();
  62. textarea.value = '';
  63. try {
  64. document.execCommand("insertText", false, s)
  65. } catch (e) {
  66. textarea.value = s;
  67. }
  68. }
  69. }
  70. await new Promise(r => requestAnimationFrame(r));
  71. if (location.pathname !== sPathname) continue;
  72. ((pathname) => {
  73. isValid = function () { return location.pathname === pathname }
  74. })(location.pathname);
  75. let textarea = document.querySelector('textarea#prompt-textarea');
  76. if (textarea && textarea.value) {
  77. map.set(location.pathname, textarea.value);
  78. }
  79. }
  80. })();
  81.  
  82. const eventHandler = (evt) => {
  83. const target = (evt || 0).target;
  84. if ((target || 0).id !== 'prompt-textarea') return;
  85. if (++tzz > 1e9) tzz = 9;
  86. if (isValid()) {
  87. jKey = location.pathname;
  88. jValue = target.value;
  89. }
  90. }
  91.  
  92. document.addEventListener('keydown', eventHandler, true);
  93. document.addEventListener('keyup', eventHandler, true);
  94. document.addEventListener('change', eventHandler, true);
  95. })();

QingJ © 2025

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