Skip to content

fix: add execCommand fallback for contenteditable input#210

Open
voidborne-d wants to merge 1 commit intoalibaba:mainfrom
voidborne-d:fix/contenteditable-fallback
Open

fix: add execCommand fallback for contenteditable input#210
voidborne-d wants to merge 1 commit intoalibaba:mainfrom
voidborne-d:fix/contenteditable-fallback

Conversation

@voidborne-d
Copy link

Problem

When Page Agent tries to type into contenteditable elements (e.g. LinkedIn post editor, #168), the synthetic event approach (Plan A) fires beforeinput/input events and sets innerText, but some editors' internal state doesn't update — the text appears momentarily then gets wiped, or never appears at all.

This happens because editors like LinkedIn's use framework-level event handlers that don't respond to synthetic InputEvent dispatches.

Solution

After executing Plan A, we now verify the text was actually inserted by checking element.innerText. If it wasn't, we automatically fall back to Plan B: execCommand.

The fallback:

  1. Focuses the element
  2. Uses Selection/Range API to select all content
  3. Deletes existing content via execCommand('delete')
  4. Inserts new text via execCommand('insertText')

Why this works

execCommand is deprecated but still widely supported by all major browsers. More importantly, it integrates natively with the browser's editing machinery — rich-text editors built on contenteditable (LinkedIn, Quill, Slate.js, ProseMirror) all respond to it correctly because it flows through the same code path as real user input.

What stays the same

  • Plan A (synthetic events) is still tried first — it works well for React contenteditable and simpler editors
  • The change/blur event dispatch is unchanged
  • No behavior change for <input> or <textarea> elements

Fixes #168

When typing into contenteditable elements (e.g. LinkedIn post editor),
the synthetic event approach (Plan A) may fail silently — the events
fire but the editor's internal state doesn't update, leaving the
element empty.

This adds an automatic fallback: after Plan A, we verify the text was
actually inserted by checking element.innerText. If it wasn't, we
fall back to execCommand('insertText') which integrates natively with
most rich-text editors including LinkedIn, Quill, and Slate.js.

The fallback uses proper Selection/Range API to select-all before
replacing, and preserves the undo stack since execCommand is handled
by the browser natively.

Fixes alibaba#168
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Can't type into LinkedIn post editor (contenteditable div)

2 participants