Skip to content

Commit

Permalink
[web] Fix EventTargetListener::dispose with AbortController invocation (
Browse files Browse the repository at this point in the history
  • Loading branch information
Schahen authored Oct 24, 2024
1 parent 69e3647 commit 0e313e2
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,28 @@

package androidx.compose.ui.events

import org.w3c.dom.AddEventListenerOptions
import org.w3c.dom.events.Event
import org.w3c.dom.events.EventTarget

private fun interface DisposableEventListener {
fun dispose()
private external interface AbortSignal
private external class AbortController {
val signal: AbortSignal
fun abort()
}

private fun EventTarget.addDisposableEvent(eventName: String, handler: (Event) -> Unit): DisposableEventListener {
addEventListener(eventName, handler)
return DisposableEventListener { removeEventListener(eventName, handler) }
}

internal class EventTargetListener(private val eventTarget: EventTarget): DisposableEventListener {
private val registeredEvents = mutableListOf<DisposableEventListener>()
private fun withSignal(signal: AbortSignal): AddEventListenerOptions = js("({signal: signal})")

internal class EventTargetListener(private val eventTarget: EventTarget) {
private val abortController = AbortController()

fun addDisposableEvent(eventName: String, handler: (Event) -> Unit) {
registeredEvents.add(eventTarget.addDisposableEvent(eventName, handler))
eventTarget.addEventListener(eventName, handler, withSignal(abortController.signal))
}

override fun dispose() {
registeredEvents.forEach { evt -> evt.dispose() }
fun dispose() {
abortController.abort()
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,9 @@ class EventTargetListenerTests {
el.dispatchEvent(MouseEvent("mousedown"))
assertEquals(listOf(1, 1, 1), log, "removing from document should not affect log")

//TODO: this won't work as supposed because lambda passed on the javascript side won't be disposed
listener.dispose()

// listener.dispose()
//
// el.dispatchEvent(MouseEvent("mousedown"))
// assertEquals(listOf(1, 1, 1), log, "after dispose log should not be updated")
el.dispatchEvent(MouseEvent("mousedown"))
assertEquals(listOf(1, 1, 1), log, "after dispose log should not be updated")
}
}

0 comments on commit 0e313e2

Please sign in to comment.