fix(page-controller): improve contenteditable input with proper events
## Problem Input into contenteditable elements (like LinkedIn post editor) fails because simply setting innerText does not trigger framework event listeners. ## Solution Dispatch a full sequence of events that rich text editors expect: - beforeinput (for React apps) - input (standard) - keydown/keyup (for keyboard listeners) - change (for validation) - blur + refocus (to trigger change detection) ## Testing Tested on: - LinkedIn post editor - Draft.js editors - Contenteditable divs with React listeners Fixes #168
This commit is contained in:
@@ -114,7 +114,53 @@ export async function inputTextElement(element: HTMLElement, text: string) {
|
|||||||
await clickElement(element)
|
await clickElement(element)
|
||||||
|
|
||||||
if (isContentEditable) {
|
if (isContentEditable) {
|
||||||
element.innerText = text
|
// For contenteditable elements (like LinkedIn editor, rich text editors),
|
||||||
|
// we need to dispatch proper events to trigger framework listeners.
|
||||||
|
// Many frameworks (React, Vue, etc.) listen to specific events.
|
||||||
|
const editableElement = element as HTMLElement & { innerText: string }
|
||||||
|
|
||||||
|
// Focus the element first
|
||||||
|
editableElement.focus()
|
||||||
|
|
||||||
|
// Clear existing content
|
||||||
|
editableElement.innerText = ''
|
||||||
|
|
||||||
|
// Dispatch beforeinput event (important for React apps)
|
||||||
|
const beforeInputEvent = new InputEvent('beforeinput', {
|
||||||
|
bubbles: true,
|
||||||
|
cancelable: true,
|
||||||
|
inputType: 'insertText',
|
||||||
|
data: text,
|
||||||
|
})
|
||||||
|
editableElement.dispatchEvent(beforeInputEvent)
|
||||||
|
|
||||||
|
// Set the text content
|
||||||
|
editableElement.innerText = text
|
||||||
|
|
||||||
|
// Dispatch input event (standard)
|
||||||
|
editableElement.dispatchEvent(new Event('input', { bubbles: true }))
|
||||||
|
|
||||||
|
// Dispatch keydown/keyup events for frameworks that listen to keyboard
|
||||||
|
const keydownEvent = new KeyboardEvent('keydown', {
|
||||||
|
bubbles: true,
|
||||||
|
cancelable: true,
|
||||||
|
key: text.slice(-1), // Last character
|
||||||
|
})
|
||||||
|
editableElement.dispatchEvent(keydownEvent)
|
||||||
|
|
||||||
|
const keyupEvent = new KeyboardEvent('keyup', {
|
||||||
|
bubbles: true,
|
||||||
|
cancelable: true,
|
||||||
|
key: text.slice(-1),
|
||||||
|
})
|
||||||
|
editableElement.dispatchEvent(keyupEvent)
|
||||||
|
|
||||||
|
// Dispatch change event (for good measure)
|
||||||
|
editableElement.dispatchEvent(new Event('change', { bubbles: true }))
|
||||||
|
|
||||||
|
// Dispatch blur and refocus to trigger any validation
|
||||||
|
editableElement.dispatchEvent(new FocusEvent('blur', { bubbles: true }))
|
||||||
|
editableElement.focus()
|
||||||
} else if (element instanceof HTMLTextAreaElement) {
|
} else if (element instanceof HTMLTextAreaElement) {
|
||||||
nativeTextAreaValueSetter.call(element, text)
|
nativeTextAreaValueSetter.call(element, text)
|
||||||
} else {
|
} else {
|
||||||
@@ -128,6 +174,7 @@ export async function inputTextElement(element: HTMLElement, text: string) {
|
|||||||
blurLastClickedElement()
|
blurLastClickedElement()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @todo browser-use version is very complex and supports menu tags, need to follow up
|
* @todo browser-use version is very complex and supports menu tags, need to follow up
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user