Quickly edit previous prompt for Superpower ChatGPT

Press Ctrl + Alt + Left click on the previous prompt text to jump in at the current mouse position to quickly edit the prompt

当前为 2024-05-09 提交的版本,查看 最新版本

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

You will need to install an extension such as Tampermonkey to install this script.

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Quickly edit previous prompt for Superpower ChatGPT
// @description  Press Ctrl + Alt + Left click on the previous prompt text to jump in at the current mouse position to quickly edit the prompt
// @author       NWP
// @namespace    https://greasyfork.org/users/877912
// @version      0.3
// @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
// 2. Launch a version for pure OpenAI

(function() {
    'use strict';

    document.addEventListener('mousedown', function(event) {
        // Check if the Ctrl and Alt keys are pressed, and the primary mouse button (left click) is used
        if (event.ctrlKey && event.altKey && event.button === 0) {
            const targetDiv = event.target;
            // Ensure the event's target is a div
            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;
                    }
                }

                // Check if we successfully got a text node and offset
                if (textNode && (offset !== undefined)) {
                    // console.log('Text node:', textNode);
                    // console.log('Offset in node:', offset);

                    if (targetDiv) {
                        // Extract the unique ID from the DIV's ID
                        const uniqueID = targetDiv.id.replace('message-text-', '');
                        // Find the corresponding button using the unique ID
                        const button = document.getElementById(`message-edit-button-${uniqueID}`);
                        if (button) {
                            // Get the scrollable container - THIS WILL LIKELY BREAK IN THE FUTURE
                            const scrollableContainer = document.querySelector('div#conversation-inner-div.h-full.overflow-y-auto');
                            // Save current scroll position
                            const x = scrollableContainer.scrollLeft, // Horizontal scroll position
                                  y = scrollableContainer.scrollTop;  // Vertical scroll position
                            // console.log(x, y);

                            // If the button exists, simulate a click on it
                            button.click();

                            // Prevent the default action to avoid any unwanted side effects
                            event.preventDefault();

                            // Wait a bit for the textarea to become visible
                            setTimeout(function() {
                                // const x1 = scrollableContainer.scrollLeft, // Horizontal scroll position
                                // y1 = scrollableContainer.scrollTop;  // Vertical scroll position
                                // console.log(x1, y1);
                                const textarea = document.getElementById(`message-text-${uniqueID}`);
                                if (textarea) {
                                    // Manually set focus without scrolling
                                    textarea.focus({preventScroll: true});
                                    textarea.setSelectionRange(offset, offset);

                                    // Restore the scroll position
                                    scrollableContainer.scrollTo(x, y);
                                }
                            }, 0); // Adjust the timeout as necessary based on how the textarea is shown
                        }
                    }
                }
            }
        }
    });


})();

// 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
//     }
//   });