fix: bypass CodeMirror posAtCoords for accurate cursor at non-100% CSS zoom

CSS zoom on document.documentElement causes a coordinate space mismatch
between mouse event clientX/Y (viewport space) and Range.getClientRects()
(CSS space), breaking CodeMirror's click-to-position mapping. The previous
requestMeasure() fix only recalibrated cached geometry, not this mismatch.

New approach: zoomCursorFix extension patches posAtCoords/posAndSideAtCoords
on the EditorView instance to use document.caretRangeFromPoint() — the
browser's native, zoom-aware API — with coord-adjustment fallback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Test
2026-03-09 10:43:46 +01:00
parent 60fd4d9ade
commit 080e5ff62d
4 changed files with 241 additions and 0 deletions

View File

@@ -66,4 +66,14 @@ describe('useCodeMirror', () => {
expect(spy).not.toHaveBeenCalled()
spy.mockRestore()
})
it('installs zoomCursorFix that overrides posAtCoords on the view instance', () => {
const ref = { current: container }
const { result } = renderHook(() =>
useCodeMirror(ref, 'hello world', false, noopCallbacks),
)
const view = result.current.current!
// The extension overrides posAtCoords on the instance (not the prototype)
expect(Object.prototype.hasOwnProperty.call(view, 'posAtCoords')).toBe(true)
})
})