Repository navigation
fix(editor): edits that lost text or acted on the wrong place - #29
Merged
Merged
Conversation
Fixes found by adversarial testing of the editor canvas: - A key pressed right after a click acted on the previous caret. - Typing into an empty paragraph saved by Word (<w:p/>) or a new table row was lost. - Cmd+A, Cmd+Up/Down, Cmd+Home/End left the caret outside every paragraph. - Word / line deletes (Option/Cmd+Backspace), Enter during IME composition, spelling suggestions and browser-menu undo let the browser restructure the DOM, so the screen and the saved document diverged. - Deleting a selection that crosses table cells did nothing. - Backspace after a table joined the paragraph to the one above the table. - Enter / Backspace in an empty list item now leave the list as in Word. - Caret formatting (Cmd+B with no selection) formats the word or the text typed next instead of the whole run. - A click in the header / footer margin moves the caret to the nearest line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UAiVj14HzKtRDqK12BXTr6
6 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This fixes editor bugs found by adversarially testing the
/editorcanvas. Several of them lost text, or made the screen differ from the saved document. Others acted on the wrong place: the previous caret, the paragraph above a table, or the whole run instead of a word.Motivation
The maintainer reported that editing "still behaves strangely" and asked for thorough adversarial testing. Every finding below was reproduced in Chromium with a harness. After each action, the harness checks three things:
There is no linked issue.
Changes
Lost or diverging text (canvas)
A key pressed right after a click acted on the previous caret, because
selectionchangehad not fired yet. For example, Enter + typing landed at the top of the document. The selection is now synced on every keydown andbeforeinput.Typing into a paragraph with no runs was rendered but never reached the model. This covers Word's empty
<w:p/>and the cells of a row added with Tab. Typing and IME there now go throughinsertTextCommand.These inputs used to let the browser restructure the DOM, and the model silently diverged from the screen:
insertParagraphfrom virtual keyboards;beforeinputnow leaves only plain typing, composition and one-character deletes inside a run to the browser. Everything else maps to the matching command, usinggetTargetRanges().⌘A selected the page box, so typing over it wrecked the pages. ⌘A now selects the story: the body, or the open header or footer.
⌘↑ / ⌘↓ / ⌘Home / ⌘End left the caret between paragraphs. They now jump paragraph by paragraph and to the document start and end, as in Word.
A click in the header or footer margin left the caret where it was. It now moves to the nearest body line.
Model commands (
@office-kit/docx-editor)deleteSelectionCommandacross table cells threw "not supported", and the canvas ignored the throw. Now:mergeBackCommandafter a table joined the paragraph to the one above the table. Now a paragraph with text stays put. An empty one is removed, unless it is the body's last paragraph, and the caret moves to the end of the last cell.Intl.Segmenter, so Japanese works);runPointsteps over the zero-width placeholder of an empty run, so typing there stays in that run.isEmptyParagraph.Word behaviour (canvas)
Testing
range-edit.test.ts: cross-cell delete, delete from a paragraph into a table and from a table out of it, Backspace after a table (3 cases).text-selection.test.ts: caret formatting for a word, a Japanese word, text typed next, and a double toggle.commands.test.ts: two bold tests used to pass only because a caret bolded the whole run. They now select the text they mean.pnpm test: 1278 passed, 8 skipped.pnpm typecheck,pnpm -r run typecheck,svelte-check,check:api-pageandcheck:tree-shakeall pass.oxlintreports the 2 known warnings./editor, en and ja: every scenario above was reproduced before the fix and passes after it. That includes CDP IME composition, Track Changes on, vertical text, a document with a bare<w:p/>, and a 40-paragraph two-page document.Breaking changes
None. Character formatting at a caret behaves differently, as described above, to match Word.
Checklist
🤖 Generated with Claude Code
https://claude.ai/code/session_01UAiVj14HzKtRDqK12BXTr6