You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Looked into this — happy to put up a PR. The chain today is: the select event is dispatched by the browser as a side effect of the native selection call (setUISelection → native setSelectionRange, via the interceptor in src/document/interceptor.ts). Like focus/blur, the browser suppresses it when document.visibilityState === 'hidden', and there's no simulated equivalent — patchFocus.ts handles focus/blur under a hidden document, but nothing covers select.
So the fix mirrors patchFocus: when the document is hidden, dispatch select ourselves after the selection actually changes. Natural hook point is the setSelectionRange interceptor's then callback (interceptor.ts:~162), which is exactly the path the repro's direct element.setSelectionRange(1, 2) goes through. One prerequisite: select isn't in src/event/eventMap.ts, so dispatchDOMEvent(el, 'select') needs an entry added first (EventType: 'Event', bubbles: true, cancelable: false).
One design question before I code it: the existing test "events are not dispatched on same microtask in browser" documents that the real browser fires selectasynchronously. Should the simulated dispatch match that (defer to a microtask), or is a synchronous dispatch in the then acceptable here? Happy to go either way — just want to match the behavior you'd expect.
Scope-wise I'd keep the first PR to setSelectionRange (the repro), and leave select() / setRangeText as a follow-up unless you'd rather cover them together.
Activity
FrancoKaddour commentedon Oct 23, 2026
Looked into this — happy to put up a PR. The chain today is: the
selectevent is dispatched by the browser as a side effect of the native selection call (setUISelection→ nativesetSelectionRange, via the interceptor insrc/document/interceptor.ts). Like focus/blur, the browser suppresses it whendocument.visibilityState === 'hidden', and there's no simulated equivalent —patchFocus.tshandles focus/blur under a hidden document, but nothing coversselect.So the fix mirrors
patchFocus: when the document is hidden, dispatchselectourselves after the selection actually changes. Natural hook point is thesetSelectionRangeinterceptor'sthencallback (interceptor.ts:~162), which is exactly the path the repro's directelement.setSelectionRange(1, 2)goes through. One prerequisite:selectisn't insrc/event/eventMap.ts, sodispatchDOMEvent(el, 'select')needs an entry added first (EventType: 'Event',bubbles: true,cancelable: false).One design question before I code it: the existing test "events are not dispatched on same microtask in browser" documents that the real browser fires
selectasynchronously. Should the simulated dispatch match that (defer to a microtask), or is a synchronous dispatch in thethenacceptable here? Happy to go either way — just want to match the behavior you'd expect.Scope-wise I'd keep the first PR to
setSelectionRange(the repro), and leaveselect()/setRangeTextas a follow-up unless you'd rather cover them together.