ChatGPT Input Protector

Prevent input words loss on ChatGPT page loading

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         ChatGPT Input Protector
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Prevent input words loss on ChatGPT page loading
// @match        https://chat.openai.com/*
// @match        https://chatgpt.com/* 
// @license MIT 
// ==/UserScript==

(function () {
    'use strict';

    const STORAGE_KEY = "chatgpt_input_cache";

    function getInputBox() {
        return document.querySelector('[contenteditable="true"]');
    }

    // 保存输入
    function saveInput(text) {
        localStorage.setItem(STORAGE_KEY, text);
    }

    // 读取输入
    function loadInput() {
        return localStorage.getItem(STORAGE_KEY) || "";
    }

    // 恢复输入
    function restoreInput(el) {
        const saved = loadInput();
        if (saved && el.innerText.trim() === "") {
            el.innerText = saved;

            // 触发 input 事件(关键!让 React 知道内容变了)
            el.dispatchEvent(new Event('input', { bubbles: true }));
        }
    }

    function init() {
        let input = getInputBox();
        if (!input) return;

        // 初次恢复
        restoreInput(input);

        // 监听输入变化
        input.addEventListener("input", () => {
            saveInput(input.innerText);
        });

        // 监听 DOM 变化(防止 React 重建)
        const observer = new MutationObserver(() => {
            let newInput = getInputBox();
            if (newInput && newInput !== input) {
                input = newInput;
                restoreInput(input);

                input.addEventListener("input", () => {
                    saveInput(input.innerText);
                });
            }
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    }

    // 等页面加载
    window.addEventListener("load", () => {
        setTimeout(init, 500);
    });

})();