Greasy Fork

Greasy Fork is available in English.

Quickly edit question for Superpower ChatGPT

Press Ctrl + Alt + Left click on the text of the question you asked to jump in at the current mouse position to quickly edit the question

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Quickly edit question for Superpower ChatGPT
// @description  Press Ctrl + Alt + Left click on the text of the question you asked to jump in at the current mouse position to quickly edit the question
// @author       NWP
// @namespace    http://greasyfork.icu/users/877912
// @version      0.4
// @license      MIT
// @match        https://chat.openai.com/*
// @match        https://chatgpt.com/*
// @grant        none
// ==/UserScript==

// TODO:
// 1. Fix the screen flicker due to the fast jumping to the Save & Submit button and then
// jumping back to the current position of the caret in the textarea, except for Chrome
// 2. Launch a version for pure OpenAI

// DONE:
// Fixed code for Firefox, enabled instant scrolling instead of smooth scrolling
// Fixed flicker for Chrome

(function() {

    if (navigator.userAgent.toLowerCase().includes('firefox')) {
        document.addEventListener('mousedown', function(event) {
            if (event.ctrlKey && event.altKey && event.button === 0) {
                const targetDiv = event.target;
                if (targetDiv.tagName === 'DIV') {
                    let textNode, offset;
                    if (document.caretPositionFromPoint) {
                        const caretPos = document.caretPositionFromPoint(event.clientX, event.clientY);
                        if (caretPos) {
                            textNode = caretPos.offsetNode;
                            offset = caretPos.offset;
                        }
                    } else if (document.caretRangeFromPoint) {
                        const range = document.caretRangeFromPoint(event.clientX, event.clientY);
                        if (range) {
                            textNode = range.startContainer;
                            offset = range.startOffset;
                        }
                    }
                    if (textNode && (offset !== undefined)) {
                        if (targetDiv) {
                            const uniqueID = targetDiv.id.replace('message-text-', '');
                            const button = document.getElementById(`message-edit-button-${uniqueID}`);
                            if (button) {
                                // scrollableContainer WILL LIKELY BREAK IN THE FUTURE
                                const scrollableContainer = document.querySelector('div#conversation-inner-div.h-full.overflow-y-auto');
                                const y = scrollableContainer.scrollTop;

                                button.click();
                                event.preventDefault();

                                setTimeout(function() {
                                    const textarea = document.getElementById(`message-text-${uniqueID}`);
                                    if (textarea) {
                                        textarea.focus({preventScroll: true});
                                        textarea.setSelectionRange(offset, offset);

                                        scrollableContainer.scrollTo({
                                            top: y,
                                            behavior: 'instant'
                                        })
                                    }
                                }, 0);
                            }
                        }
                    }
                }
            }
        });

        console.log("The browser is Firefox.")

    } else {
        document.addEventListener('mousedown', function(event) {
            if (event.ctrlKey && event.altKey && event.button === 0) {
                const targetDiv = event.target;
                if (targetDiv.tagName === 'DIV' && targetDiv.id.startsWith('message-text-')) {
                    event.preventDefault();
                    let textNode, offset;
                    const pointMethod = document.caretPositionFromPoint ? 'caretPositionFromPoint' : 'caretRangeFromPoint';
                    const caretResult = document[pointMethod](event.clientX, event.clientY);

                    if (caretResult) {
                        textNode = caretResult.offsetNode || caretResult.startContainer;
                        offset = caretResult.offset !== undefined ? caretResult.offset : caretResult.startOffset;
                    }

                    if (textNode && offset !== undefined) {
                        const uniqueID = targetDiv.id.replace('message-text-', '');
                        const button = document.getElementById(`message-edit-button-${uniqueID}`);
                        if (button) {
                            // scrollableContainer WILL LIKELY BREAK IN THE FUTURE
                            const scrollableContainer = document.querySelector('div#conversation-inner-div.h-full.overflow-y-auto');
                            const originalScroll = { x: scrollableContainer.scrollLeft, y: scrollableContainer.scrollTop };

                            button.click();

                            const observer = new MutationObserver((mutations, obs) => {
                                const textarea = document.getElementById(`message-text-${uniqueID}`);
                                if (textarea && textarea.offsetHeight > 0 && document.activeElement === textarea) {
                                    textarea.setSelectionRange(offset, offset);
                                    scrollableContainer.scrollTo({
                                        top: originalScroll.y,
                                        behavior: 'instant'
                                    });
                                    obs.disconnect();
                                }
                            });

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

        console.log("The browser is not Firefox.")
    }


})();


// When scrollableContainer breaks use this code to find the new scrollableContainer element:

// function isScrollable(element) {
//     const hasScrollableContent = element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
//     const overflowStyle = window.getComputedStyle(element).overflow;
//     return hasScrollableContent && (overflowStyle === 'scroll' || overflowStyle === 'auto');
//   }

//   // Find all elements in the body
//   const allElements = document.querySelectorAll('body, body *');

//   // Counter variable to track index
//   let index = 1;

//   // Filter out scrollable elements and apply a red border
//   Array.from(allElements).forEach(element => {
//     if (isScrollable(element)) {
//       element.style.border = '2px solid red';
//       console.log("Scrollable Element " + index + ":", element);
//       console.log("Scroll Position " + index + " (x, y):", element.scrollLeft, element.scrollTop);
//       index++; // Increment index for the next scrollable element
//     }
//   });