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

ติดตั้งสคริปต์นี้?
สคริปต์ที่แนะนำของผู้เขียน

คุณอาจชื่นชอบ Save & Submit keyboard shortcut for ChatGPT

ติดตั้งสคริปต์นี้
// ==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    https://greasyfork.org/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
//     }
//   });