Repository navigation
Conversation
|
Thanks for working on this. The issue still exists on main (8ca7911), so the fix is worth pursuing. However, testing the patch against that revision in real Chrome exposed a few issues that should be addressed before merging:
Could you extend the implementation to distinguish the editing host from the requested target and explicitly constrain the selection to that target? Simply redirecting the operation to the parent editor could also expand the clearing scope unintentionally. Please also add real-browser regression coverage for replacement, append, background tabs, and preserving sibling content. The new mocked test bypasses the focus and selection behavior responsible for these failures. I’d recommend keeping this PR open and addressing these issues before merging, especially the unintended content modification. 17:49 |
DOM.describeNode only reports the target's own attributes. A paragraph inside [contenteditable] has none, so fill rejected it before the live isContentEditable check. Agents snapshot the inner block of rich editors and then cannot type into it.
A descendant of a contenteditable host is now checked for live editability before anything is focused, so a non-editable target is rejected without blurring the focused element. Its editing host takes focus, which a paragraph without tabindex cannot, and the selection is confined to the target: its contents are selected to be replaced, or the caret is put at their end to append, after background focus handling. Clearing no longer empties the target before typing, which let the typed text land in the next paragraph. Real-browser tests cover replacement, append, an empty value, background tabs and sibling paragraphs, and run in the browser input CI job. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fbcd687 to
3569319
Compare
|
@iuyo5678 Thanks for testing this in a real browser. All three failures reproduced with a real Chrome, and they are fixed in 3569319, rebased onto current
Real-browser coverage is in the new |
|
Thanks for the update! This is a substantial improvement. I re-tested 3569319: the ordinary paragraph, replacement, append, background-tab, and non-editable focus cases now behave correctly. All 18 new browser tests also passed locally. Two remaining edge cases came up during additional testing:
Could you add browser regressions for empty targets, clear-then-refill, and multiline input? For any cases that cannot yet be supported safely, rejecting them before modifying the page would be a reasonable interim approach. The remaining scope is much narrower now. I’d still address these before merging, particularly the empty-target case, because it can modify content outside the requested target. Thanks again for the implementation improvements and the real-browser coverage. |
Two cases from review could still change content outside the target:
- An empty target. Chrome moves a caret in an empty element out to a
neighbouring text node before inserting, so filling an empty <p> (or
one just cleared with fill("")) typed into a sibling. The target now
gets a zero-width placeholder to type over, replacing Chrome's own
empty-line <br> when that is all it holds, and a placeholder left by
a fill that stops early is removed. An element holding only that <br>
reads as empty rather than a newline.
- A value with line breaks. Typing a newline in an editing host splits
the target into new paragraphs, which then fails verification after
the page has changed. A descendant target now rejects such a value
with fill_value_invalid before anything is focused or changed; the
editing host itself still takes multiline values.
Adds real-browser regressions for empty targets (paragraph, paragraph
with <br>, span; replace and append), clear-then-refill, and multiline
rejection in foreground and background tabs.
|
@iuyo5678 Thanks for the extra testing. Both cases reproduced in headless Chrome and are handled in e2fc4f7:
New browser regressions, each run in foreground and background tabs:
All 42 tests in |
Reject editor descendants before scrolling, focusing, or changing content. Remove temporary placeholders and verify root focus and caret placement. Add shared browser evals for replacement, append, clearing, rejection, cancellation, and editor discovery.
Text nodes, <br>, and direct <div> lines, the layouts Chrome creates while typing, are now read with the same rules: a <br> that only holds a line open is not a character, collapsible whitespace at line edges is ignored, and an empty line without a <br> has no height. This replaces three layout-specific branches and fixes appending to an editor that ends with <br>, which wrote the text and then failed verification. Share the white-space collapsing check with fill preparation, and add regressions for a trailing <br> and source-formatted line wrappers.
|
@kevin9327 Thank you for sticking with this through several rounds. Your real-browser harness and regression cases made it possible to pin down exactly where the behavior breaks, and the final version builds directly on them. While re-testing e2fc4f7, three more issues came up: a paragraph containing only ordinary spaces could still write into its neighbour, cancelling right after the placeholder was inserted could leave a hidden character behind, and the placeholder cleanup could in rare cases remove a character the user actually asked to fill. They share one root cause: Chrome inserts text at the canonical visible position within the editing host, not at the DOM range we set, so a fill cannot reliably be confined to a descendant. Rich-text editors also re-render their own paragraph nodes. Rather than ask for another round of edge-case fixes, we narrowed the contract and pushed two commits on top of your branch. Your commits are unchanged. Contract
A descendant is rejected with Changes
Behaviour change to note An element that repeats Verification (merged with current
Follow-ups, out of scope here Editing a single paragraph inside a long document is a real need, but it fits poorly with fill's replace/append semantics. A separate capability that places the caret or selection (for example via I'd like to retitle this PR to |
Problem
bsk fillrejected a<p>(or other inner block) inside acontenteditableeditor withtarget_not_fillable.DOM.describeNodeonly reports the target's own attributes. Snapshot refs for TipTap, ProseMirror, Notion-style editors point at the inner paragraph, which has nocontenteditableattribute even thoughelement.isContentEditableis true. Fill never reached the live editability check.Change
Treat unknown tags as maybe-fillable so the live
isContentEditablecheck can accept inherited editability. Keep rejecting controls that fill cannot drive (button,select, media, and similar).Testing
pnpm --filter @browser-skill/extension exec vitest run src/tools/__tests__/fill.test.ts -t contenteditablepnpm --filter @browser-skill/extension testAI-assisted (Grok)