Repository navigation
Suggest mode 5/9: inline suggestion operations - #80431
adamsilverstein wants to merge 69 commits into
Conversation
Adds the suggestion-specific layer on top of the marker primitive: create, accept, and reject inline text (add/del) and formatting suggestions (operations.js); the pure reconcilers that turn a text edit or a format toggle into marker actions (reconcile-edit.js, reconcile-format.js); word/ line delete-range resolution; strip-markers for clean attribute snapshots; findSuggestionText/findMarkerText helpers; and the annotate-suggestions hook. Still pure modules - the keyboards and reconcilers that call them into the live editor land in the final step.
|
Size Change: 0 B Total Size: 7.93 MB |
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
Flaky tests detected in d690668. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/33117688052 refuses the drop and uploads nothing in
|
Trunk switched @wordpress/dependency-group to 'never' mode, so the import group headers in these files now fail lint.
Rename the files this PR adds from .js to .ts and add types so the strict type check covers them: the edit/format reconcilers now export TextEdit, MarkerAction, and FormatPlan interfaces, and marker/op helpers carry typed signatures. No behavior changes.
# Conflicts: # packages/components/CHANGELOG.md
# Conflicts: # packages/editor/CHANGELOG.md
Accepting an addition, rejecting a deletion or accepting a format suggestion removed the suggestion format across the whole range from the id's first fragment to its last, so another suggestion sitting in the gap was resolved along with it. Unwrap only the runs that carry the resolved id, sharing the run walk removeMarkedRange already used. Claude-Session: https://claude.ai/code/session_01EmSXGAGtuLnk3UEe5kXPSU
|
Claude reproduced this one first, then fixed it:
|
The prefix/suffix trim worked on UTF-16 code units, so changing an emoji next to one with the same high surrogate left lone halves in the removed and inserted text, which then reached saved content. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YHz7zkCC2S8crriSWsYPDk
The appliers leave anything but RichTextData untouched, so a plain string attribute got a plan, a new note, and no marker. Returning no plan keeps those edits on the overlay path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YHz7zkCC2S8crriSWsYPDk
Planning and applying a marker serialized each RichTextData value to HTML and parsed it back, about four cycles per keystroke. Read the record RichTextData already holds, scan formats instead of HTML for the marker probes, and bail out of the format planner as soon as the text differs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YHz7zkCC2S8crriSWsYPDk
Reading `RichTextData` directly left `toRichTextRecord` returning a union with the class's `never[]` array types, so every rich-text helper call on its result failed to type-check, and `hasSuggestionMarkers` could not iterate the formats at all. Declare the record as a `RichTextValue` and type the scanned formats the same way. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MnVknLuyvKfR9DsM4H3SrX
A format marker nests inside the formatting it proposes, and an inline image inserted as a suggested addition loses its image. Both tests fail until the reconcilers are fixed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011duzHshRK8Jud89VQ6BZZB
…ions applyFormat nests a new format inside the formats a range shares, so a bolded run saved as <strong><mark>…</mark></strong>. Stamping the marker outside the run's formatting lets the front end swap the whole span for the original run. An inline image is an object replacement character with no formats, so the edit reconciler rebuilt the inserted run as plain text and dropped the image. Serialize the run whenever it carries objects, leave out only an inherited suggestion marker, and pass the HTML when growing the author's own addition as well. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011duzHshRK8Jud89VQ6BZZB
Part of #73411
What's in this PR
Adds the suggestion-specific layer on top of the marker primitive: create,
accept, and reject inline text (add/del) and formatting suggestions
(operations.js); the pure reconcilers that turn a text edit or a format
toggle into marker actions (reconcile-edit.js, reconcile-format.js); word/
line delete-range resolution; strip-markers for clean attribute snapshots;
findSuggestionText/findMarkerText helpers; and the annotate-suggestions hook.
Still pure modules - the keyboards and reconcilers that call them into the
live editor land in the final step.
Diagram
Pure transforms over a rich-text value: write a marker, resolve it on accept or reject, strip it for output.
Testing
This is one layer of the stack. To exercise the whole feature, #78994 bundles every layer into one branch and builds it in Playground:
👉 https://playground.wordpress.net/gutenberg.html?pr=78994
Enable Gutenberg > Experiments > Collaboration > Suggestion Mode, then follow the walkthrough in #73411, which also explains how to review the stack layer by layer.
Suggest mode stack
This rebuilds the manually-stacked Suggest mode work (#73411) as a GitHub Stack of 9 small, independently reviewable PRs, each building on the one below it:
Each follow up fix now sits in the layer that owns the code it changes, rather than piling onto the top of the stack. The whole feature can be exercised end-to-end via the combined testing branch #78994 (Playground). Behind the "Suggestion Mode" experiment (Gutenberg > Experiments).
AI Use
Code and description both written with 🤖 Claude Code. I will review and test.