fix(comments): don't drop DOCX comments containing bookmark nodes (#3828)#3829
fix(comments): don't drop DOCX comments containing bookmark nodes (#3828)#3829gpardhivvarma wants to merge 2 commits into
Conversation
…perdoc-dev#3828) DOCX comments with `w:bookmarkStart`/`w:bookmarkEnd` nodes were silently dropped from the loaded comments list. The comment JSON is built against the full DOCX schema (which registers bookmark nodes), but `getHtmlFromComment` renders the display HTML with the reduced rich-text schema (`getRichTextExtensions()`), which does not. `normalizeCommentForEditor` forwarded the bookmark nodes verbatim, so `nodeFromJSON` threw `Unknown node type: bookmarkStart`; the error was swallowed and the guard `if (!htmlContent && !comment.trackedChange) return;` discarded the comment. Normalize defensively: drop/unwrap any node type the rich-text schema does not register (not just bookmarks), deriving the supported-node set directly from the extension objects' `.type`/`.name`. Invisible leaf nodes are dropped; nodes wrapping content are unwrapped so the visible text survives. The original `docxCommentJSON` is untouched, so exported bookmark metadata is preserved. The normalizer is extracted into a pure `comment-normalize.js` module so it can be unit-tested directly. Adds fast unit tests plus an end-to-end regression test that exercises the real headless Editor (the existing suite mocks it, so it could not reproduce the schema throw).
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 258a63949a
ℹ️ 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".
Code Review by Qodo
Context used 1.
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
|
hey @caio-pizzol . Can you please take a look at this. Coudn't contribute for some time because of some personal reasons. Good to be back |
Address automated review feedback on superdoc-dev#3829: - normalizeCommentForEditor mapped every unsupported leaf node to null, which silently dropped visible whitespace separators (lineBreak/hardBreak/tab) that can appear in imported comment JSON (comments import via the same defaultNodeListHandler as body content). Map those visible leaves to text so the separation survives in the rendered HTML instead of joining words. - comments-store.bookmark.test.js enabled fake timers in beforeEach without restoring them; add afterEach(vi.useRealTimers()) to match the established pattern and avoid cross-test contamination.
|
Addressed the automated review feedback in 547d560:
All 145 local tests pass (8 unit + 1 e2e + 136 existing). Re the two red CI checks ( |
|
Code review by qodo was updated up to the latest commit 547d560 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 547d560065
ℹ️ 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 VISIBLE_LEAF_NODE_TEXT = { | ||
| lineBreak: '\n', | ||
| hardBreak: '\n', | ||
| tab: '\t', | ||
| }; |
There was a problem hiding this comment.
Preserve no-break hyphens in comment text
When a DOCX comment contains <w:noBreakHyphen/>, the importer emits a noBreakHyphen leaf whose visible text is U+2011, but getRichTextExtensions() does not register NoBreakHyphenNode, so this new unsupported-leaf path returns null because the leaf is absent from this map. That makes sidebar text like co‑author render as coauthor rather than preserving the visible hyphen; include noBreakHyphen: '‑' before dropping unsupported leaves.
Useful? React with 👍 / 👎.
Summary
Fixes #3828. DOCX comments containing
w:bookmarkStart/w:bookmarkEndnodes were silently dropped from the loaded comments list, withRangeError: Unknown node type: bookmarkStart/Failed to convert commentlogged to the console.Root cause
A comment's imported ProseMirror JSON (
comment.elements) is produced against the full DOCX schema, which registersbookmarkStart/bookmarkEnd. ButgetHtmlFromCommentrenders the comment's display HTML with a throwaway headlessEditorbuilt from the reduced rich-text schema (getRichTextExtensions()), which does not register those nodes.normalizeCommentForEditorforwarded the bookmark nodes verbatim, so ProseMirror'snodeFromJSONthrewUnknown node type: bookmarkStart. Thetry/catchingetHtmlFromCommentswallowed the error and returnedundefined, and the guardif (!htmlContent && !comment.trackedChange) return;inprocessLoadedDocxCommentsthen discarded the entire comment.Fix
Normalize defensively: drop or unwrap any node type the rich-text schema does not register — not just bookmarks — so this whole class of crash is prevented (stray
lineBreak,tab, etc. would fail the same way). The supported-node set is derived directly from the extension objects'.type/.name(ProseMirror adds no implicit nodes, so no schema construction is needed).docxCommentJSONis untouched, so exported bookmark metadata is preserved on round-trip.The normalizer is extracted into a pure
comment-normalize.jsmodule so it can be unit-tested directly.Tests
comment-normalize.test.js(new) — fast, pure unit tests: bookmark stripping, unknown-node unwrap/drop, supported-node passthrough,textStylefont-attr stripping, and the empty-set fallback (strip bookmarks only).comments-store.bookmark.test.js(new) — end-to-end regression test using the real headlessEditor(the existingcomments-store.test.jsmocksEditor, so it could not reproduce the schema throw). Verified to fail before the fix (comment dropped) and pass after.comments-storetests still pass.Files
packages/superdoc/src/stores/comment-normalize.js(new) — defensive normalizer +getRichTextSupportedNodeNames.packages/superdoc/src/stores/comments-store.js— import the helpers, remove the inline normalizer, thread the supported-node set throughgetHtmlFromComment.packages/superdoc/src/stores/comment-normalize.test.js,packages/superdoc/src/stores/comments-store.bookmark.test.js(new tests).