Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/lib/litegraph/src/LGraphCanvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { forEachNode } from '@/utils/graphTraversalUtil'

import { CanvasPointer } from './CanvasPointer'
import type { ContextMenu } from './ContextMenu'
import { createCursorCache } from './cursorCache'
import { DragAndScale } from './DragAndScale'
import type { AnimationOptions } from './DragAndScale'
import type { LGraph } from './LGraph'
Expand Down Expand Up @@ -364,6 +365,8 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
this.canvas.dispatchEvent(new CustomEvent(type, { detail }))
}

private _setCursor!: ReturnType<typeof createCursorCache>

private _updateCursorStyle() {
if (!this.state.shouldSetCursor) return

Expand All @@ -386,7 +389,7 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
cursor = 'grab'
}

this.canvas.style.cursor = cursor
this._setCursor(cursor)
}

// Whether the canvas was previously being dragged prior to pressing space key.
Expand Down Expand Up @@ -1911,6 +1914,7 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
this.pointer.element = element

if (!element) return
this._setCursor = createCursorCache(element)

// TODO: classList.add
element.className += ' lgraphcanvas'
Expand Down Expand Up @@ -2970,7 +2974,7 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
}

// Set appropriate cursor for resize direction
this.canvas.style.cursor = cursors[resizeDirection]
this._setCursor(cursors[resizeDirection])
return
}
}
Expand Down
59 changes: 59 additions & 0 deletions src/lib/litegraph/src/cursorCache.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { describe, expect, it, vi } from 'vitest'

import { createCursorCache } from './cursorCache'

function createMockElement() {
let cursorValue = ''
const setter = vi.fn((value: string) => {
cursorValue = value
})

const element = document.createElement('div')
Object.defineProperty(element.style, 'cursor', {
get: () => cursorValue,
set: setter
})

return { element, setter }
}

describe('createCursorCache', () => {
it('should only write to DOM when cursor value changes', () => {
const { element, setter } = createMockElement()
const setCursor = createCursorCache(element)

setCursor('crosshair')
setCursor('crosshair')
setCursor('crosshair')

expect(setter).toHaveBeenCalledTimes(1)
expect(setter).toHaveBeenCalledWith('crosshair')
})

it('should write to DOM when cursor value differs', () => {
const { element, setter } = createMockElement()
const setCursor = createCursorCache(element)

setCursor('default')
setCursor('crosshair')
setCursor('grabbing')

expect(setter).toHaveBeenCalledTimes(3)
expect(setter).toHaveBeenNthCalledWith(1, 'default')
expect(setter).toHaveBeenNthCalledWith(2, 'crosshair')
expect(setter).toHaveBeenNthCalledWith(3, 'grabbing')
})

it('should skip repeated values interspersed with changes', () => {
const { element, setter } = createMockElement()
const setCursor = createCursorCache(element)

setCursor('default')
setCursor('default')
setCursor('grab')
setCursor('grab')
setCursor('default')

expect(setter).toHaveBeenCalledTimes(3)
})
})
8 changes: 8 additions & 0 deletions src/lib/litegraph/src/cursorCache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export function createCursorCache(element: HTMLElement) {
let lastCursor = ''
return function setCursor(cursor: string) {
if (cursor === lastCursor) return
lastCursor = cursor
element.style.cursor = cursor
}
}
Loading