Repository navigation
fix: don't double-map positions in the visual editor's sync-heading-links handler - #1228
Open
kevinushey wants to merge 2 commits into
Open
kevinushey wants to merge 2 commits into
kevinushey wants to merge 2 commits into
Conversation
The sync-heading-links append handler scanned link and heading positions from tr.doc, which already reflects every step on the transaction, then mapped them through tr.mapping again. When an earlier append handler in the same pass had changed the document (figure-convert turning a linked image into a figure), each position was shifted twice, and a link near the end of the document resolved past it: "RangeError: Position N out of range" when switching RStudio from Source to Visual (rstudio/rstudio#19588).
Contributor
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
2 of 4 tasks
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.
In the visual editor, switching a document from source to visual fails with
RangeError: Position N out of rangewhen the document contains an image wrapped in a link ([](https://...)) and ends with a link. Reported in rstudio/rstudio#19588; the reporter's attachment reproduces it on every switch after the first.Cause
syncHeadingLinksAppendTransaction()(packages/editor/src/marks/link/link-headings.ts) scans link and heading positions fromtr.docand then maps them throughtr.mapping. Buttr.docalready reflects every step ontr, so any step taken before the scan is applied to those positions twice.The append handlers share one transaction, and
figure-convert(registered bynodeFigure, ahead ofmarkLink) runs first. WhensetMarkdownreloads the document, it turns each linked image back into a figure, which lengthens the document beforesync-heading-linksscans it. Every link position then lands too far along. In the middle of the document that is silently harmless, since the handler only acts on links bound to a heading. A link near the end is pushed past the end of the document, andtr.doc.resolve()throws.Stack from the repro:
appendTransaction->sync-heading-linksappend(link-headings.ts:68) ->Node.resolve.The inner loop that rewrites links after a heading is renamed had the same problem within the handler itself: when two linked headings are renamed in one transaction, the link scan for the second heading also maps through the text inserted for the first.
Fix
Each scan records
tr.mapping.maps.lengthbeforehand, and its positions are mapped throughtr.mapping.slice(start), i.e. only through the steps added after that scan. This is the same guarantee the other append handlers get fromtrTransform(), which runs them against a freshTransform.Tests
packages/editor/test/link-headings.test.tsdrives the handler directly against a minimal schema:headingattribute is out of date, with the same earlier step;All three fail before the change: the first two throw
RangeError: Position N out of range, and the third leaves the second link's text andheadingattribute stale. They pass after it, along with the rest of the editor suite.Verification
With panmirror built from this branch and served by an RStudio dev server, the reporter's document (CRLF and LF copies) switches source -> visual -> source -> visual twice with no error. With the panmirror currently pinned by RStudio, it fails on the first switch back to visual.