mirror of
https://github.com/stablyai/orca.git
synced 2026-10-01 08:01:56 +00:00
fix(editor): skip shift-wheel capture when a diff pane cannot scroll sideways
Word-wrapped panes never overflow horizontally, so consuming the gesture left it dead instead of reaching the outer combined-diff list.
This commit is contained in:
@@ -9,9 +9,11 @@ type PaneFixture = {
|
||||
setScrollLeft: ReturnType<typeof vi.fn<(value: number) => void>>
|
||||
getScrollLeft: () => number
|
||||
getContainerDomNode: () => HTMLElement
|
||||
getScrollWidth: () => number
|
||||
getLayoutInfo: () => { contentWidth: number }
|
||||
}
|
||||
|
||||
function createPaneFixture(initialScrollLeft = 10): PaneFixture {
|
||||
function createPaneFixture(initialScrollLeft = 10, scrollWidth = 1000): PaneFixture {
|
||||
const container = document.createElement('div')
|
||||
const input = document.createElement('div')
|
||||
let scrollLeft = initialScrollLeft
|
||||
@@ -26,7 +28,9 @@ function createPaneFixture(initialScrollLeft = 10): PaneFixture {
|
||||
input,
|
||||
setScrollLeft,
|
||||
getScrollLeft: () => scrollLeft,
|
||||
getContainerDomNode: () => container
|
||||
getContainerDomNode: () => container,
|
||||
getScrollWidth: () => scrollWidth,
|
||||
getLayoutInfo: () => ({ contentWidth: 200 })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +97,26 @@ describe('installDiffEditorShiftWheelScroll', () => {
|
||||
dispose()
|
||||
})
|
||||
|
||||
it('scrolls the modified pane independently', () => {
|
||||
it('leaves shift input alone when the pane has no horizontal overflow', () => {
|
||||
const original = createPaneFixture(0, 200)
|
||||
const modified = createPaneFixture(0, 200)
|
||||
const onDownstreamWheel = vi.fn()
|
||||
original.input.addEventListener('wheel', onDownstreamWheel)
|
||||
const dispose = installDiffEditorShiftWheelScroll({
|
||||
getOriginalEditor: () => original,
|
||||
getModifiedEditor: () => modified
|
||||
})
|
||||
|
||||
const event = dispatchWheel(original.input, { deltaY: 24, shiftKey: true })
|
||||
|
||||
expect(event.defaultPrevented).toBe(false)
|
||||
expect(original.setScrollLeft).not.toHaveBeenCalled()
|
||||
expect(onDownstreamWheel).toHaveBeenCalledTimes(1)
|
||||
dispose()
|
||||
})
|
||||
|
||||
// Monaco syncs pane scroll itself; this covers listener routing, not product-level pane independence.
|
||||
it('routes the wheel event to the pane under the pointer', () => {
|
||||
const original = createPaneFixture()
|
||||
const modified = createPaneFixture()
|
||||
const dispose = installDiffEditorShiftWheelScroll({
|
||||
|
||||
@@ -4,8 +4,8 @@ const WHEEL_LINE_PIXELS = 16
|
||||
|
||||
type HorizontalScrollEditor = Pick<
|
||||
editor.ICodeEditor,
|
||||
'getContainerDomNode' | 'getScrollLeft' | 'setScrollLeft'
|
||||
>
|
||||
'getContainerDomNode' | 'getScrollLeft' | 'setScrollLeft' | 'getScrollWidth'
|
||||
> & { getLayoutInfo: () => Pick<editor.EditorLayoutInfo, 'contentWidth'> }
|
||||
|
||||
type DiffEditorWithPanes = {
|
||||
getModifiedEditor: () => HorizontalScrollEditor
|
||||
@@ -23,6 +23,10 @@ function getHorizontalWheelPixels(event: WheelEvent, pageWidth: number): number
|
||||
return delta
|
||||
}
|
||||
|
||||
function canScrollHorizontally(editor: HorizontalScrollEditor): boolean {
|
||||
return editor.getScrollWidth() > editor.getLayoutInfo().contentWidth
|
||||
}
|
||||
|
||||
function installPaneShiftWheelScroll(editor: HorizontalScrollEditor): () => void {
|
||||
const container = editor.getContainerDomNode()
|
||||
const handleWheel = (event: WheelEvent): void => {
|
||||
@@ -30,6 +34,11 @@ function installPaneShiftWheelScroll(editor: HorizontalScrollEditor): () => void
|
||||
return
|
||||
}
|
||||
|
||||
// Why: a word-wrapped pane never overflows sideways, so leave the gesture to the outer list.
|
||||
if (!canScrollHorizontally(editor)) {
|
||||
return
|
||||
}
|
||||
|
||||
const delta = getHorizontalWheelPixels(event, container.clientWidth)
|
||||
if (delta === 0) {
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user