feat(word-diff): implement word-level diffing for granular text changes#2817
Conversation
There was a problem hiding this comment.
π‘ Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 38564682d3
βΉοΈ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with π.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const textNode = editor.state.schema.text(trimmedNew, asProseMirrorMarks(marks)); | ||
| tr.replaceWith(trimmedFrom, trimmedTo, textNode); |
There was a problem hiding this comment.
Avoid creating empty text nodes for delete-only rewrites
In executeTextRewrite, the single-change path always does schema.text(trimmedNew) even when the trimmed diff is a pure deletion. For inputs like removing a word ("The quick fox" β "The fox"), trimmedNew becomes "", and ProseMirror rejects empty text nodes at runtime, aborting the rewrite instead of applying the delete. This regression is introduced by the new prefix/suffix trimming flow and will surface on common delete-only edits.
Useful? React with πΒ / π.
| const segments = this.collectTextSegments(from, to); | ||
| const nodes = this.buildTextNodes(from, to, change.newText, segments); |
There was a problem hiding this comment.
Read replacement marks from transaction doc after remapping
applyGranularChanges remaps later change positions through prior tr.steps, but then calls collectTextSegments(from, to) on this.editor.state.doc (the original document). After an earlier insert/delete changes length, those remapped positions no longer point to the same content in the original doc, so subsequent replacements can inherit marks from the wrong region (or none), causing formatting loss/corruption in multi-change tracked edits.
Useful? React with πΒ / π.
|
π This PR is included in vscode-ext v2.3.0-next.18 |
|
π This PR is included in @superdoc-dev/react v1.2.0-next.15 The release is available on GitHub release |
|
π This PR is included in template-builder v1.5.0-next.18 The release is available on GitHub release |
|
π This PR is included in esign v2.3.0-next.18 The release is available on GitHub release |
|
π This PR is included in superdoc v1.26.0-next.18 The release is available on GitHub release |
|
π This PR is included in superdoc-cli v0.7.0-next.19 The release is available on GitHub release |
|
π This PR is included in superdoc-sdk v1.6.0-next.16 |
The word-diff executor added in #2817 calls `tr.doc.textBetween(...)` and `tr.doc.nodesBetween(...)` in the text.rewrite path, but the `tr.doc` mocks in determinism-stress, executor, and preview-parity tests were never updated to match. That broke determinism-stress, executeCompiledPlan, previewPlan, and revision-drift-guard tests on main with `TypeError: tr.doc.textBetween is not a function` / `doc.nodesBetween is not a function`.
* test(superdoc): add unit tests for pdf, comments, and pdf-viewer Adds test coverage for previously untested files: - core/pdf/pdf-adapter.js β factory, adapter, CDN worker helper - components/CommentsLayer/use-conversation.js β conversation composable - components/CommentsLayer/use-floating-comment.js β floating comment state - components/CommentsLayer/CommentGroup.vue β grouped comment rendering - components/PdfViewer/PdfViewer.vue β top-level viewer with adapter mocks - components/PdfViewer/PdfViewerDocument.vue β page list wrapper - components/PdfViewer/PdfViewerPage.vue β page render + text layer 62 new tests. Lifts filtered coverage from 78.6% to 81.1%. * test(superdoc): add tests for composables and comments list - composables/use-field.js β useField + sub-handlers (SELECT/IMAGE/CHECKBOX) - composables/use-ai.js β AI writer cursor positioning, fallbacks, tool click - components/CommentsLayer/commentsList/super-comments-list.js β Vue app lifecycle - components/Whiteboard/use-whiteboard.js β event wiring, page ready, teardown 46 new tests. Lifts filtered coverage 81.1% β 83.3%. * test(superdoc): cover WhiteboardPage canvas interactions Mock Konva Stage/Layer/Line/Text/Image/Transformer and trigger stage/text-node event listeners to exercise the interactive code paths: draw/erase flows, stage click handlers (text + select), text node selection + drag + Delete, image node events. 38 tests. Lifts WhiteboardPage coverage 40% β 81%, package 83.3% β 88.5%. * fix(test): add textBetween/nodesBetween to plan-engine tr.doc mocks The word-diff executor added in #2817 calls `tr.doc.textBetween(...)` and `tr.doc.nodesBetween(...)` in the text.rewrite path, but the `tr.doc` mocks in determinism-stress, executor, and preview-parity tests were never updated to match. That broke determinism-stress, executeCompiledPlan, previewPlan, and revision-drift-guard tests on main with `TypeError: tr.doc.textBetween is not a function` / `doc.nodesBetween is not a function`. * test(superdoc): push coverage past 90% Add targeted tests to close remaining gaps: - use-comment extended β resolveComment, setIsInternal, setText, mentions - superdoc-store extended β reset, getDocument, handlePageReady, getPageBounds, areDocumentsReady, setExceptionHandler, collaboration mode - Whiteboard extended β tool/enabled propagation, opacity clamping, callbacks - New small files: comment-schemas, DocumentUsers.vue, SuperToolbar.vue, use-selection, CommentsLayer/helpers formatDate Lifts package coverage from 83.3% to 90.1%.
No description provided.