feat: add undo functionality for enhance prompt feature (fixes #5741) (#5742)

Co-authored-by: Roo <roo@roocode.dev>
Co-authored-by: Matt Rubens <mrubens@users.noreply.github.com>
This commit is contained in:
roomote[bot] 2025-07-15 10:26:34 -04:00 committed by GitHub
parent 29b7d06dd2
commit ab1756961c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 90 additions and 4 deletions

View file

@ -115,8 +115,25 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
const message = event.data
if (message.type === "enhancedPrompt") {
if (message.text) {
setInputValue(message.text)
if (message.text && textAreaRef.current) {
try {
// Use execCommand to replace text while preserving undo history
if (document.execCommand) {
// Use native browser methods to preserve undo stack
const textarea = textAreaRef.current
// Focus the textarea to ensure it's the active element
textarea.focus()
// Select all text first
textarea.select()
document.execCommand("insertText", false, message.text)
} else {
setInputValue(message.text)
}
} catch {
setInputValue(message.text)
}
}
setIsEnhancingPrompt(false)

View file

@ -184,10 +184,27 @@ describe("ChatTextArea", () => {
})
describe("enhanced prompt response", () => {
it("should update input value when receiving enhanced prompt", () => {
it("should update input value using native browser methods when receiving enhanced prompt", () => {
const setInputValue = vi.fn()
render(<ChatTextArea {...defaultProps} setInputValue={setInputValue} />)
// Mock document.execCommand
const mockExecCommand = vi.fn().mockReturnValue(true)
Object.defineProperty(document, "execCommand", {
value: mockExecCommand,
writable: true,
})
const { container } = render(
<ChatTextArea {...defaultProps} setInputValue={setInputValue} inputValue="Original prompt" />,
)
const textarea = container.querySelector("textarea")!
// Mock textarea methods
const mockSelect = vi.fn()
const mockFocus = vi.fn()
textarea.select = mockSelect
textarea.focus = mockFocus
// Simulate receiving enhanced prompt message
window.dispatchEvent(
@ -199,8 +216,54 @@ describe("ChatTextArea", () => {
}),
)
// Verify native browser methods were used
expect(mockFocus).toHaveBeenCalled()
expect(mockSelect).toHaveBeenCalled()
expect(mockExecCommand).toHaveBeenCalledWith("insertText", false, "Enhanced test prompt")
})
it("should fallback to setInputValue when execCommand is not available", () => {
const setInputValue = vi.fn()
// Mock document.execCommand to be undefined (not available)
Object.defineProperty(document, "execCommand", {
value: undefined,
writable: true,
})
render(<ChatTextArea {...defaultProps} setInputValue={setInputValue} inputValue="Original prompt" />)
// Simulate receiving enhanced prompt message
window.dispatchEvent(
new MessageEvent("message", {
data: {
type: "enhancedPrompt",
text: "Enhanced test prompt",
},
}),
)
// Verify fallback to setInputValue was used
expect(setInputValue).toHaveBeenCalledWith("Enhanced test prompt")
})
it("should not crash when textarea ref is not available", () => {
const setInputValue = vi.fn()
render(<ChatTextArea {...defaultProps} setInputValue={setInputValue} />)
// Simulate receiving enhanced prompt message when textarea ref might not be ready
expect(() => {
window.dispatchEvent(
new MessageEvent("message", {
data: {
type: "enhancedPrompt",
text: "Enhanced test prompt",
},
}),
)
}).not.toThrow()
})
})
describe("multi-file drag and drop", () => {

View file

@ -1,6 +1,12 @@
import "@testing-library/jest-dom"
import "@testing-library/jest-dom/vitest"
// Force React into development mode for tests
// This is needed to enable act(...) function in React Testing Library
globalThis.process = globalThis.process || {}
globalThis.process.env = globalThis.process.env || {}
globalThis.process.env.NODE_ENV = "development"
class MockResizeObserver {
observe() {}
unobserve() {}