fix: cursor drift during vertical arrow navigation (SD-1689)#1918
fix: cursor drift during vertical arrow navigation (SD-1689)#1918luccas-harbour wants to merge 21 commits intomainfrom
Conversation
af96315 to
09421f5
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 09421f5954
ℹ️ 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".
packages/super-editor/src/extensions/vertical-navigation/vertical-navigation.js
Outdated
Show resolved
Hide resolved
3ded6e3 to
94c3fcf
Compare
afn
left a comment
There was a problem hiding this comment.
Looks good to the best of my understanding! Had a couple of minor suggestions but nothing blocking.
| const pageEl = options.painterHost.querySelector( | ||
| `.superdoc-page[data-page-index="${options.pageIndex}"]`, |
There was a problem hiding this comment.
Consider making this a helper function (and replace several other places in the codebase that are querying the DOM for data-page-index) to encapsulate the implementation details
There was a problem hiding this comment.
It turns out there was already a helper for this here so I am referencing it instead.
| * @param options - Configuration object containing DOM elements and page information. | ||
| * @returns The Y offset in layout-space units, or null if calculation fails. | ||
| */ | ||
| export function getPageOffsetY(options: { |
There was a problem hiding this comment.
This seems to duplicate the contents of getPageOffsets(). Why not use that method (or wrap it like getPageOffsetX) instead?
There was a problem hiding this comment.
Good call! I should have double checked this one
| // Upper-bound search for pmStart <= pos | ||
| let lo = 0; | ||
| let hi = entries.length; | ||
| while (lo < hi) { | ||
| const mid = (lo + hi) >>> 1; | ||
| if (entries[mid].pmStart <= pos) { | ||
| lo = mid + 1; | ||
| } else { | ||
| hi = mid; | ||
| } | ||
| } | ||
|
|
||
| const idx = lo - 1; |
There was a problem hiding this comment.
Binary search is notoriously tricky to get right :) Consider using something like lodash's sortedIndexBy (lodash isn't currently a direct dependency of superdoc-editor, but it's pulled in via naive-ui) to simplify the code and avoid potential pitfalls.
| // Upper-bound search for pmStart <= pos | |
| let lo = 0; | |
| let hi = entries.length; | |
| while (lo < hi) { | |
| const mid = (lo + hi) >>> 1; | |
| if (entries[mid].pmStart <= pos) { | |
| lo = mid + 1; | |
| } else { | |
| hi = mid; | |
| } | |
| } | |
| const idx = lo - 1; | |
| const idx = sortedIndexBy(entries, { pmStart: pos }, 'pmStart') - 1; |
There was a problem hiding this comment.
Sounds good, I changed it
| * @param {boolean} extend | ||
| * @returns {import('prosemirror-state').Selection | null} | ||
| */ | ||
| function buildSelection(state, pos, extend) { |
There was a problem hiding this comment.
Consider moving this function to a place where it can be used by other extensions if needed, perhaps src/core/presentation-editor/selection/SelectionHelpers.ts?
There was a problem hiding this comment.
I had a look at this one and it looks quite simple and specific to what is being done in this plugin so I think I'd rather keep it as a local function. I could not find anywhere else in the codebase that would benefit from this helper.
I don't think it would really fit in src/core/presentation-editor/selection/SelectionHelpers.ts as it modifies the selection from the ProseMirror side of things, whereas the code in the SelectionHelpers file deals with rendering concerns from the layout-engine's side.
4d9c694 to
e710bcc
Compare
packages/super-editor/src/extensions/vertical-navigation/vertical-navigation.js
Outdated
Show resolved
Hide resolved
packages/super-editor/src/extensions/vertical-navigation/vertical-navigation.js
Show resolved
Hide resolved
packages/super-editor/src/extensions/vertical-navigation/vertical-navigation.js
Outdated
Show resolved
Hide resolved
packages/super-editor/src/extensions/vertical-navigation/vertical-navigation.js
Show resolved
Hide resolved
| let entry = options.domPositionIndex.findEntryClosestToPosition(pos); | ||
| if (entry && !entry.el.isConnected) { | ||
| options.rebuildDomPositionIndex(); | ||
| entry = options.domPositionIndex.findEntryAtPosition(pos); |
There was a problem hiding this comment.
is it on purpose to use findEntryAtPosition here instead of findEntryClosestToPosition?
There was a problem hiding this comment.
I hadn't modified it because during my tests execution never entered the if statement but now after checking the code, I see it makes sense to change it there too. Done.
| * @param height - Optional layout height to scale into screen pixels. | ||
| * @returns The client-space point (and optional height), or null if inputs are not finite. | ||
| */ | ||
| export function denormalizeClientPoint( |
There was a problem hiding this comment.
q: denormalizeClientPoint adds pageOffsetY but normalizeClientPoint doesn't subtract it - is this intentional?
There was a problem hiding this comment.
I hadn't touched normalizeClientPoint as I saw it was being used in other places but now I investigated it a bit more deeply and indeed that looks like a mistake. I fixed it.
| baseX = layoutX + pageOffsetX; | ||
| } | ||
|
|
||
| const pageOffsetY = options.getPageOffsetY(pageIndex); |
There was a problem hiding this comment.
nit: X uses let baseX = layoutX then modifies baseX, but Y mutates the param directly
|
@caio-pizzol this PR will likely conflict with this one: #1944 let's wait until that other one is merged and then I can handle the conflicts and we can merge this one |
6c2f9f3 to
6d68731
Compare
|
@luccas-harbour fyi #1944 is now merged |
6d68731 to
2c62bd0
Compare
|
@harbournick @caio-pizzol this has been rebased on top of main and is ready for re-review/merge |
Shiftis held.